## Automatically generated incremental diff
## From:   linux-2.4.20-pre6
## To:     linux-2.4.20-pre7
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.4.20-pre6/Documentation/BK-usage/bk-kernel-howto.txt linux-2.4.20-pre7/Documentation/BK-usage/bk-kernel-howto.txt
--- linux-2.4.20-pre6/Documentation/BK-usage/bk-kernel-howto.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/bk-kernel-howto.txt	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,275 @@
+
+		   Doing the BK Thing, Penguin-Style
+
+
+
+
+This set of notes is intended mainly for kernel developers, occasional
+or full-time, but sysadmins and power users may find parts of it useful
+as well.  It assumes at least a basic familiarity with CVS, both at a
+user level (use on the cmd line) and at a higher level (client-server model).
+Due to the author's background, an operation may be described in terms
+of CVS, or in terms of how that operation differs from CVS.
+
+This is -not- intended to be BitKeeper documentation.  Always run
+"bk help <command>" or in X "bk helptool <command>" for reference
+documentation.
+
+
+BitKeeper Concepts
+------------------
+
+In the true nature of the Internet itself, BitKeeper is a distributed
+system.  When applied to revision control, this means doing away with
+client-server, and changing to a parent-child model... essentially
+peer-to-peer.  On the developer's end, this also represents a
+fundamental disruption in the standard workflow of changes, commits,
+and merges.  You will need to take a few minutes to think about
+how to best work under BitKeeper, and re-optimize things a bit.
+In some sense it is a bit radical, because it might described as
+tossing changes out into a maelstrom and having them magically
+land at the right destination... but I'm getting ahead of myself.
+
+Let's start with this progression:
+Each BitKeeper source tree on disk is a repository unto itself.
+Each repository has a parent.
+Each repository contains a set of a changesets ("csets").
+Each cset is one or more changed files, bundled together.
+
+Each tree is a repository, so all changes are checked into the local
+tree.  When a change is checked in, all modified files are grouped
+into a logical unit, the changeset.  Internally, BK links these
+changesets in a tree, representing various converging and diverging
+lines of development.  These changesets are the bread and butter of
+the BK system.
+
+After the concept of changesets, the next thing you need to get used
+to is having multiple copies of source trees lying around.  This -really-
+takes some getting used to, for some people.  Separate source trees
+are the means in BitKeeper by which you delineate parallel lines
+of development, both minor and major.  What would be branches in
+CVS become separate source trees, or "clones" in BitKeeper [heh,
+or Star Wars] terminology.
+
+Clones and changesets are the tools from which most of the power of
+BitKeeper is derived.  As mentioned earlier, each clone has a parent,
+the tree used as the source when the new clone was created.  In a
+CVS-like setup, the parent would be a remote server on the Internet,
+and the child is your local clone of that tree.
+
+Once you have established a common baseline between two source trees --
+a common parent -- then you can merge changesets between those two
+trees with ease.  Merging changes into a tree is called a "pull", and
+is analagous to 'cvs update'.  A pull downloads all the changesets in
+the remote tree you do not have, and merges them.  Sending changes in
+one tree to another tree is called a "push".  Push sends all changes
+in the local tree the remote does not yet have, and merges them.
+
+From these concepts come some initial command examples:
+
+1) bk clone -q http://linux.bkbits.net/linux-2.5 linus-2.5
+Download a 2.5 stock kernel tree, naming it "linus-2.5" in the local dir.
+The "-q" disables listing every single file as it is downloaded.
+
+2) bk clone -ql linus-2.5 alpha-2.5
+Create a separate source tree for the Alpha AXP architecture.
+The "-l" uses hard links instead of copying data, since both trees are
+on the local disk.  You can also replace the above with "bk lclone -q ..."
+
+You only clone a tree -once-.  After cloning the tree lives a long time
+on disk, being updating by pushes and pulls.
+
+3) cd alpha-2.5 ; bk pull http://gkernel.bkbits.net/alpha-2.5
+Download changes in "alpha-2.5" repository which are not present
+in the local repository, and merge them into the source tree.
+
+4) bk -r co -q
+Because every tree is a repository, files must be checked out before
+they will be in their standard places in the source tree.
+
+5)	bk vi fs/inode.c				# example change...
+	bk citool					# checkin, using X tool
+	bk push bk://gkernel@bkbits.net/alpha-2.5	# upload change
+Typical example of a BK sequence that would replace the analagous CVS
+situation,
+	vi fs/inode.c
+	cvs commit
+
+As this is just supposed to be a quick BK intro, for more in-depth
+tutorials, live working demos, and docs, see http://www.bitkeeper.com/
+
+
+
+BK and Kernel Development Workflow
+----------------------------------
+Currently the latest 2.5 tree is available via "bk clone $URL"
+and "bk pull $URL" at http://linux.bkbits.net/linux-2.5
+This should change in a few weeks to a kernel.org URL.
+
+
+A big part of using BitKeeper is organizing the various trees you have
+on your local disk, and organizing the flow of changes among those
+trees, and remote trees.  If one were to graph the relationships between
+a desired BK setup, you are likely to see a few-many-few graph, like
+this:
+
+		    linux-2.5
+		        |
+	       merge-to-linus-2.5
+		 /    |      |
+	        /     |      |
+	vm-hacks  bugfixes  filesys   personal-hacks
+	      \	      |	     |		/
+	       \      |      |         /
+		\     |      |        /
+	         testing-and-validation
+
+Since a "bk push" sends all changes not in the target tree, and
+since a "bk pull" receives all changes not in the source tree, you want
+to make sure you are only pushing specific changes to the desired tree,
+not all changes from "peer parent" trees.  For example, pushing a change
+from the testing-and-validation tree would probably be a bad idea,
+because it will push all changes from vm-hacks, bugfixes, filesys, and
+personal-hacks trees into the target tree.
+
+One would typically work on only one "theme" at a time, either
+vm-hacks or bugfixes or filesys, keeping those changes isolated in
+their own tree during development, and only merge the isolated with
+other changes when going upstream (to Linus or other maintainers) or
+downstream (to your "union" trees, like testing-and-validation above).
+
+It should be noted that some of this separation is not just recommended
+practice, it's actually [for now] -enforced- by BitKeeper.  BitKeeper
+requires that changesets maintain a certain order, which is the reason
+that "bk push" sends all local changesets the remote doesn't have.  This
+separation may look like a lot of wasted disk space at first, but it
+helps when two unrelated changes may "pollute" the same area of code, or
+don't follow the same pace of development, or any other of the standard
+reasons why one creates a development branch.
+
+Small development branches (clones) will appear and disappear:
+
+	-------- A --------- B --------- C --------- D -------
+	          \                                 /
+		   -----short-term devel branch-----
+
+While long-term branches will parallel a tree (or trees), with period
+merge points.  In this first example, we pull from a tree (pulls,
+"\") periodically, such as what occurs when tracking changes in a
+vendor tree, never pushing changes back up the line:
+
+	-------- A --------- B --------- C --------- D -------
+	          \                       \           \
+	           ----long-term devel branch-----------------
+
+And then a more common case in Linux kernel development, a long term
+branch with periodic merges back into the tree (pushes, "/"):
+
+	-------- A --------- B --------- C --------- D -------
+	          \                       \         / \
+	           ----long-term devel branch-----------------
+
+
+
+
+
+Submitting Changes to Linus
+---------------------------
+There's a bit of an art, or style, of submitting changes to Linus.
+Since Linus's tree is now (you might say) fully integrated into the
+distributed BitKeeper system, there are several prerequisites to
+properly submitting a BitKeeper change.  All these prereq's are just
+general cleanliness of BK usage, so as people become experts at BK, feel
+free to optimize this process further (assuming Linus agrees, of
+course).
+
+
+
+0) Make sure your tree was originally cloned from the linux-2.5 tree
+created by Linus.  If your tree does not have this as its ancestor, it
+is impossible to reliably exchange changesets.
+
+
+
+1) Pay attention to your commit text.  The commit message that
+accompanies each changeset you submit will live on forever in history,
+and is used by Linus to accurately summarize the changes in each
+pre-patch.  Remember that there is no context, so
+	"fix for new scheduler changes"
+would be too vague, but
+	"fix mips64 arch for new scheduler switch_to(), TIF_xxx semantics"
+would be much better.
+
+You can and should use the command "bk comment -C<rev>" to update the
+commit text, and improve it after the fact.  This is very useful for
+development: poor, quick descriptions during development, which get
+cleaned up using "bk comment" before issuing the "bk push" to submit the
+changes.
+
+
+
+2) Include an Internet-available URL for Linus to pull from, such as
+
+	Pull from:  http://gkernel.bkbits.net/net-drivers-2.5
+
+
+
+3) Include a summary and "diffstat -p1" of each changeset that will be
+downloaded, when Linus issues a "bk pull".  The author auto-generates
+these summaries using "bk push -nl <parent> 2>&1", to obtain a listing
+of all the pending-to-send changesets, and their commit messages.
+
+It is important to show Linus what he will be downloading when he issues
+a "bk pull", to reduce the time required to sift the changes once they
+are downloaded to Linus's local machine.
+
+IMPORTANT NOTE:  One of the features of BK is that your repository does
+not have to be up to date, in order for Linus to receive your changes.
+It is considered a courtesy to keep your repository fairly recent, to
+lessen any potential merge work Linus may need to do.
+
+
+4) Split up your changes.  Each maintainer<->Linus situation is likely
+to be slightly different here, so take this just as general advice.  The
+author splits up changes according to "themes" when merging with Linus.
+Simultaneous pushes from local development go to special trees which
+exist solely to house changes "queued" for Linus.  Example of the trees:
+
+	net-drivers-2.5 -- on-going net driver maintenance
+	vm-2.5 -- VM-related changes
+	fs-2.5 -- filesystem-related changes
+
+Linus then has much more freedom for pulling changes.  He could (for
+example) issue a "bk pull" on vm-2.5 and fs-2.5 trees, to merge their
+changes, but hold off net-drivers-2.5 because of a change that needs
+more discussion.
+
+Other maintainers may find that a single linus-pull-from tree is
+adequate for passing BK changesets to him.
+
+
+
+Frequently Answered Questions
+-----------------------------
+1) How do I change the e-mail address shown in the changelog?
+A. When you run "bk citool" or "bk commit", set environment
+   variables BK_USER and BK_HOST to the desired username
+   and host/domain name.
+
+
+2) How do I use tags / get a diff between two kernel versions?
+A. Pass the tags Linus uses to 'bk export'.
+
+ChangeSets are in a forward-progressing order, so it's pretty easy
+to get a snapshot starting and ending at any two points in time.
+Linus puts tags on each release and pre-release, so you could use
+these two examples:
+
+    bk export -tpatch -hdu -rv2.5.4,v2.5.5 | less
+        # creates patch-2.5.5 essentially
+    bk export -tpatch -du -rv2.5.5-pre1,v2.5.5 | less
+        # changes from pre1 to final
+
+A tag is just an alias for a specific changeset... and since changesets
+are ordered, a tag is thus a marker for a specific point in time (or
+specific state of the tree).
diff -urN linux-2.4.20-pre6/Documentation/BK-usage/bk-make-sum linux-2.4.20-pre7/Documentation/BK-usage/bk-make-sum
--- linux-2.4.20-pre6/Documentation/BK-usage/bk-make-sum	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/bk-make-sum	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,37 @@
+#!/bin/sh -e
+# DIR=$HOME/BK/axp-2.5
+# cd $DIR
+
+LINUS_REPO=$1
+DIRBASE=`basename $PWD`
+
+{
+cat <<EOT
+Linus, please do a
+
+	bk pull http://gkernel.bkbits.net/$DIRBASE
+
+This will update the following files:
+
+EOT
+
+bk changes -L -d'$unless(:MERGE:){:CSETREV:\n}' $LINUS_REPO |
+while read rev; do
+  bk export -tpatch -r$rev
+done | diffstat -p1 2>/dev/null
+
+cat <<EOT
+
+through these ChangeSets:
+
+EOT
+
+bk changes -L -d'$unless(:MERGE:){ChangeSet|:CSETREV:\n}' $LINUS_REPO |
+bk -R prs -h -d'$unless(:MERGE:){<:P:@:HOST:> (:D: :I:)\n$each(:C:){   (:C:)\n}\n}' -
+
+} > /tmp/linus.txt
+
+cat <<EOT
+Mail text in /tmp/linus.txt; please check and send using your favourite
+mailer.
+EOT
diff -urN linux-2.4.20-pre6/Documentation/BK-usage/bksend linux-2.4.20-pre7/Documentation/BK-usage/bksend
--- linux-2.4.20-pre6/Documentation/BK-usage/bksend	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/bksend	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,36 @@
+#!/bin/sh
+# A script to format BK changeset output in a manner that is easy to read.
+# Andreas Dilger <adilger@turbolabs.com>  13/02/2002
+#
+# Add diffstat output after Changelog <adilger@turbolabs.com>   21/02/2002
+
+PROG=bksend
+
+usage() {
+	echo "usage: $PROG -r<rev>"
+	echo -e "\twhere <rev> is of the form '1.23', '1.23..', '1.23..1.27',"
+	echo -e "\tor '+' to indicate the most recent revision"
+
+	exit 1
+}
+
+case $1 in
+-r) REV=$2; shift ;;
+-r*) REV=`echo $1 | sed 's/^-r//'` ;;
+*) echo "$PROG: no revision given, you probably don't want that";;
+esac
+
+[ -z "$REV" ] && usage
+
+echo "You can import this changeset into BK by piping this whole message to:"
+echo "'| bk receive [path to repository]' or apply the patch as usual."
+
+SEP="\n===================================================================\n\n"
+echo -e $SEP
+bk changes -r$REV
+echo
+bk export -tpatch -du -h -r$REV | diffstat
+echo; echo
+bk export -tpatch -du -h -r$REV
+echo -e $SEP
+bk send -wgzip_uu -r$REV -
diff -urN linux-2.4.20-pre6/Documentation/BK-usage/bz64wrap linux-2.4.20-pre7/Documentation/BK-usage/bz64wrap
--- linux-2.4.20-pre6/Documentation/BK-usage/bz64wrap	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/bz64wrap	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# bz64wrap - the sending side of a bzip2 | base64 stream
+# Andreas Dilger <adilger@clusterfs.com>   Jan 2002
+
+
+PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin
+
+# A program to generate base64 encoding on stdout
+BASE64_ENCODE="uuencode -m /dev/stdout"
+BASE64_BEGIN=
+BASE64_END=
+
+BZIP=NO
+BASE64=NO
+
+# Test if we have the bzip program installed
+bzip2 -c /dev/null > /dev/null 2>&1 && BZIP=YES
+
+# Test if uuencode can handle the -m (MIME) encoding option
+$BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES
+
+if [ $BASE64 = NO ]; then
+	BASE64_ENCODE=mimencode
+	BASE64_BEGIN="begin-base64 644 -"
+	BASE64_END="===="
+
+	$BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES
+fi
+
+if [ $BZIP = NO -o $BASE64 = NO ]; then
+	echo "$0: can't use bz64 encoding: bzip2=$BZIP, $BASE64_ENCODE=$BASE64"
+	exit 1
+fi
+
+# Sadly, mimencode does not appear to have good "begin" and "end" markers
+# like uuencode does, and it is picky about getting the right start/end of
+# the base64 stream, so we handle this internally.
+echo "$BASE64_BEGIN"
+bzip2 -9 | $BASE64_ENCODE
+echo "$BASE64_END"
diff -urN linux-2.4.20-pre6/Documentation/BK-usage/cset-to-linus linux-2.4.20-pre7/Documentation/BK-usage/cset-to-linus
--- linux-2.4.20-pre6/Documentation/BK-usage/cset-to-linus	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/cset-to-linus	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,49 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my ($lhs, $rev, $tmp, $rhs, $s);
+my @cset_text = ();
+my @pipe_text = ();
+my $have_cset = 0;
+
+while (<>) {
+	next if /^---/;
+
+	if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) {
+		&cset_rev if ($have_cset);
+
+		$rev = $tmp;
+		$have_cset = 1;
+
+		push(@cset_text, $_);
+	}
+
+	elsif ($have_cset) {
+		push(@cset_text, $_);
+	}
+}
+&cset_rev if ($have_cset);
+exit(0);
+
+
+sub cset_rev {
+	my $empty_cset = 0;
+
+	open PIPE, "bk export -tpatch -hdu -r $rev | diffstat -p1 2>/dev/null |" or die;
+	while ($s = <PIPE>) {
+		$empty_cset = 1 if ($s =~ /0 files changed/);
+		push(@pipe_text, $s);
+	}
+	close(PIPE);
+
+	if (! $empty_cset) {
+		print @cset_text;
+		print @pipe_text;
+		print "\n\n";
+	}
+
+	@pipe_text = ();
+	@cset_text = ();
+}
+
diff -urN linux-2.4.20-pre6/Documentation/BK-usage/csets-to-patches linux-2.4.20-pre7/Documentation/BK-usage/csets-to-patches
--- linux-2.4.20-pre6/Documentation/BK-usage/csets-to-patches	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/csets-to-patches	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my ($lhs, $rev, $tmp, $rhs, $s);
+my @cset_text = ();
+my @pipe_text = ();
+my $have_cset = 0;
+
+while (<>) {
+	next if /^---/;
+
+	if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) {
+		&cset_rev if ($have_cset);
+
+		$rev = $tmp;
+		$have_cset = 1;
+
+		push(@cset_text, $_);
+	}
+
+	elsif ($have_cset) {
+		push(@cset_text, $_);
+	}
+}
+&cset_rev if ($have_cset);
+exit(0);
+
+
+sub cset_rev {
+	my $empty_cset = 0;
+
+	system("bk export -tpatch -du -r $rev > /tmp/rev-$rev.patch");
+
+	if (! $empty_cset) {
+		print @cset_text;
+		print @pipe_text;
+		print "\n\n";
+	}
+
+	@pipe_text = ();
+	@cset_text = ();
+}
+
diff -urN linux-2.4.20-pre6/Documentation/BK-usage/unbz64wrap linux-2.4.20-pre7/Documentation/BK-usage/unbz64wrap
--- linux-2.4.20-pre6/Documentation/BK-usage/unbz64wrap	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/Documentation/BK-usage/unbz64wrap	Thu Sep 12 20:01:38 2002
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# unbz64wrap - the receiving side of a bzip2 | base64 stream
+# Andreas Dilger <adilger@clusterfs.com>   Jan 2002
+
+# Sadly, mimencode does not appear to have good "begin" and "end" markers
+# like uuencode does, and it is picky about getting the right start/end of
+# the base64 stream, so we handle this explicitly here.
+
+PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin
+
+if mimencode -u < /dev/null > /dev/null 2>&1 ; then
+	SHOW=
+	while read LINE; do
+		case $LINE in
+		begin-base64*) SHOW=YES ;;
+		====) SHOW= ;;
+		*) [ "$SHOW" ] && echo $LINE ;;
+		esac
+	done | mimencode -u | bunzip2
+	exit $?
+else
+	cat - | uudecode -o /dev/stdout | bunzip2
+	exit $?
+fi
diff -urN linux-2.4.20-pre6/Documentation/Configure.help linux-2.4.20-pre7/Documentation/Configure.help
--- linux-2.4.20-pre6/Documentation/Configure.help	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/Documentation/Configure.help	Thu Sep 12 20:01:38 2002
@@ -2588,7 +2588,7 @@
   Documentation/modules.txt.  If unsure, say `N'.
 
 DSCP match support
-CONFIG_IP_NF_TARGET_DSCP
+CONFIG_IP_NF_MATCH_DSCP
   This option adds a `DSCP' match, which allows you to match against
   the IPv4 header DSCP field (DSCP codepoint).
 
@@ -13773,6 +13773,14 @@
 CONFIG_USB_SERIAL_KEYSPAN_USA19W
   Say Y here to include firmware for the USA-19W converter.
 
+USB Keyspan USA-19QW Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW
+  Say Y here to include firmware for the USA-19QW converter.
+
+USB Keyspan USA-19QI Firmware
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI
+  Say Y here to include firmware for the USA-19QI converter.
+
 USB Keyspan USA-49W Firmware
 CONFIG_USB_SERIAL_KEYSPAN_USA49W
   Say Y here to include firmware for the USA-49W converter.
@@ -18583,9 +18591,10 @@
 CONFIG_NVRAM
   If you say Y here and create a character special file /dev/nvram
   with major number 10 and minor number 144 using mknod ("man mknod"),
-  you get read and write access to the 50 bytes of non-volatile memory
-  in the real time clock (RTC), which is contained in every PC and
-  most Ataris.
+  you get read and write access to the extra bytes of non-volatile
+  memory in the real time clock (RTC), which is contained in every PC
+  and most Ataris.  The actual number of bytes varies, depending on the
+  nvram in the system, but is usually 114 (128-14 for the RTC).
 
   This memory is conventionally called "CMOS RAM" on PCs and "NVRAM"
   on Ataris. /dev/nvram may be used to view settings there, or to
@@ -19802,6 +19811,12 @@
   Say Y or M if you have a sound system driven by ESS's Maestro 3
   PCI sound chip.
 
+ForteMedia FM801 driver
+CONFIG_SOUND_FORTE
+  Say Y or M if you want driver support for the ForteMedia FM801 PCI
+  audio controller (Abit AU10, Genius Sound Maker, HP Workstation
+  zx2000, and others).
+
 Adlib Cards
 CONFIG_SOUND_ADLIB
   Includes ASB 64 4D. Information on programming AdLib cards is
diff -urN linux-2.4.20-pre6/MAINTAINERS linux-2.4.20-pre7/MAINTAINERS
--- linux-2.4.20-pre6/MAINTAINERS	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/MAINTAINERS	Thu Sep 12 20:01:39 2002
@@ -811,7 +811,7 @@
 IOC3 DRIVER
 P:	Ralf Baechle
 M:	ralf@oss.sgi.com
-L:	linux-mips@oss.sgi.com
+L:	linux-mips@linux-mips.org
 S:	Maintained
 
 IP MASQUERADING:
@@ -1023,7 +1023,7 @@
 P:	Ralf Baechle
 M:	ralf@gnu.org
 W:	http://oss.sgi.com/mips/mips-howto.html
-L:	linux-mips@oss.sgi.com
+L:	linux-mips@linux-mips.org
 S:	Maintained
 
 MISCELLANEOUS MCA-SUPPORT
@@ -1273,7 +1273,7 @@
 PHILIPS NINO PALM PC
 P:	Steven Hill
 M:	sjhill@realitydiluted.com
-L:	linux-mips@oss.sgi.com
+L:	linux-mips@linux-mips.org
 W:	http://www.realitydiluted.com/projects/nino
 S:	Maintained
 
diff -urN linux-2.4.20-pre6/Makefile linux-2.4.20-pre7/Makefile
--- linux-2.4.20-pre6/Makefile	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/Makefile	Thu Sep 12 20:01:39 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 20
-EXTRAVERSION = -pre6
+EXTRAVERSION = -pre7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.20-pre6/arch/i386/kernel/entry.S linux-2.4.20-pre7/arch/i386/kernel/entry.S
--- linux-2.4.20-pre6/arch/i386/kernel/entry.S	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/arch/i386/kernel/entry.S	Thu Sep 12 20:01:39 2002
@@ -639,6 +639,16 @@
 	.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 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_set_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_get_thread_area */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 245 sys_io_setup */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_destroy */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_getevents */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_submit */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_io_cancel */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 250 sys_alloc_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_free_hugepages */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_exit_group */
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -urN linux-2.4.20-pre6/arch/i386/kernel/pci-pc.c linux-2.4.20-pre7/arch/i386/kernel/pci-pc.c
--- linux-2.4.20-pre6/arch/i386/kernel/pci-pc.c	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/arch/i386/kernel/pci-pc.c	Thu Sep 12 20:01:39 2002
@@ -1307,6 +1307,22 @@
 	}
 }
 
+/*
+ * For some reasons Intel decided that certain parts of their
+ * 815, 845 and some other chipsets must look like PCI-to-PCI bridges
+ * while they are obviously not. The 82801 family (AA, AB, BAM/CAM,
+ * BA/CA/DB and E) PCI bridges are actually HUB-to-PCI ones, according
+ * to Intel terminology. These devices do forward all addresses from
+ * system to PCI bus no matter what are their window settings, so they are
+ * "transparent" (or subtractive decoding) from programmers point of view.
+ */
+static void __init pci_fixup_transparent_bridge(struct pci_dev *dev)
+{
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+	    (dev->device & 0xff00) == 0x2400)
+		dev->transparent = 1;
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82451NX,	pci_fixup_i450nx },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454GX,	pci_fixup_i450gx },
@@ -1321,6 +1337,7 @@
 	{ 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 },
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_ANY_ID,			pci_fixup_transparent_bridge },
 	{ 0 }
 };
 
diff -urN linux-2.4.20-pre6/arch/ia64/Makefile linux-2.4.20-pre7/arch/ia64/Makefile
--- linux-2.4.20-pre6/arch/ia64/Makefile	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/Makefile	Thu Sep 12 20:01:39 2002
@@ -22,10 +22,10 @@
 # -ffunction-sections
 CFLAGS_KERNEL := -mconstant-gp
 
-GCC_VERSION=$(shell $(CROSS_COMPILE)$(HOSTCC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
+GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
 
 ifneq ($(GCC_VERSION),2)
-	CFLAGS += -frename-registers --param max-inline-insns=2000
+	CFLAGS += -frename-registers --param max-inline-insns=5000
 endif
 
 ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y)
@@ -33,16 +33,11 @@
 endif
 
 ifdef CONFIG_IA64_GENERIC
-	CORE_FILES      :=      arch/$(ARCH)/hp/hp.a	\
-				arch/$(ARCH)/sn/sn.o	\
-				arch/$(ARCH)/dig/dig.a	\
-				arch/$(ARCH)/sn/io/sgiio.o \
+	CORE_FILES      :=      arch/$(ARCH)/hp/hp.o			\
+				arch/$(ARCH)/dig/dig.a			\
 				$(CORE_FILES)
 	SUBDIRS		:=	arch/$(ARCH)/hp		\
-				arch/$(ARCH)/sn/sn1	\
-				arch/$(ARCH)/sn		\
 				arch/$(ARCH)/dig	\
-				arch/$(ARCH)/sn/io	\
 				$(SUBDIRS)
 
 else # !GENERIC
@@ -50,7 +45,16 @@
 ifdef CONFIG_IA64_HP_SIM
         SUBDIRS         :=      arch/$(ARCH)/hp		\
                                 $(SUBDIRS)
-        CORE_FILES      :=      arch/$(ARCH)/hp/hp.a	\
+        CORE_FILES      :=      arch/$(ARCH)/hp/hp.o	\
+                                $(CORE_FILES)
+endif
+
+ifdef CONFIG_IA64_HP_ZX1
+        SUBDIRS         :=      arch/$(ARCH)/hp				\
+				arch/$(ARCH)/dig			\
+                                $(SUBDIRS)
+        CORE_FILES      :=      arch/$(ARCH)/hp/hp.o			\
+				arch/$(ARCH)/dig/dig.a			\
                                 $(CORE_FILES)
 endif
 
diff -urN linux-2.4.20-pre6/arch/ia64/boot/Makefile linux-2.4.20-pre7/arch/ia64/boot/Makefile
--- linux-2.4.20-pre6/arch/ia64/boot/Makefile	Thu Jan  4 12:50:17 2001
+++ linux-2.4.20-pre7/arch/ia64/boot/Makefile	Thu Sep 12 20:01:39 2002
@@ -27,6 +27,6 @@
 	-o bootloader
 
 clean:
-	rm -f $(TARGETS)
+	rm -f $(targets-y) $(OBJECTS)
 
 dep:
diff -urN linux-2.4.20-pre6/arch/ia64/config.in linux-2.4.20-pre7/arch/ia64/config.in
--- linux-2.4.20-pre6/arch/ia64/config.in	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/arch/ia64/config.in	Thu Sep 12 20:01:39 2002
@@ -26,29 +26,32 @@
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
 
-if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
-  define_bool CONFIG_ACPI y
-  define_bool CONFIG_ACPI_EFI y
-  define_bool CONFIG_ACPI_INTERPRETER y
-  define_bool CONFIG_ACPI_KERNEL_CONFIG y
-fi
-
 choice 'IA-64 processor type' \
-	"Itanium			CONFIG_ITANIUM \
-	 McKinley			CONFIG_MCKINLEY" Itanium
+	"Itanium		CONFIG_ITANIUM \
+	 Itanium-2		CONFIG_MCKINLEY" Itanium
 
 choice 'IA-64 system type'					\
 	"generic		CONFIG_IA64_GENERIC		\
 	 DIG-compliant		CONFIG_IA64_DIG			\
 	 HP-simulator		CONFIG_IA64_HP_SIM		\
+	 HP-zx1			CONFIG_IA64_HP_ZX1		\
 	 SGI-SN1		CONFIG_IA64_SGI_SN1		\
 	 SGI-SN2		CONFIG_IA64_SGI_SN2" generic
 
-choice 'Kernel page size'						\
+if [ "$CONFIG_ITANIUM" = "y" ]; then
+  choice 'Kernel page size'						\
+	"4KB			CONFIG_IA64_PAGE_SIZE_4KB		\
+	 8KB			CONFIG_IA64_PAGE_SIZE_8KB		\
+	 16KB			CONFIG_IA64_PAGE_SIZE_16KB" 16KB
+else
+  choice 'Kernel page size'						\
 	"4KB			CONFIG_IA64_PAGE_SIZE_4KB		\
 	 8KB			CONFIG_IA64_PAGE_SIZE_8KB		\
 	 16KB			CONFIG_IA64_PAGE_SIZE_16KB		\
 	 64KB			CONFIG_IA64_PAGE_SIZE_64KB" 16KB
+fi
+
+bool 'Virtually mapped mem_map?' CONFIG_VIRTUAL_MEM_MAP n
 
 if [ "$CONFIG_ITANIUM" = "y" ]; then
 	define_bool CONFIG_IA64_BRL_EMU y
@@ -68,21 +71,17 @@
 	fi
 fi
 
-if [ "$CONFIG_IA64_DIG" = "y" ]; then
+if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_HP_ZX1" = "y" ]; then
 	bool '  Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
 	define_bool CONFIG_PM y
 fi
 
-if [ "$CONFIG_IA64_SGI_SN1" = "y" ] || [ "$CONFIG_IA64_SGI_SN2" = "y" ]; then
+if [ "$CONFIG_IA64_SGI_SN1" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then
 	define_bool CONFIG_IA64_SGI_SN y
 	bool '  Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG
 	bool '  Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN_SIM
 	bool '  Enable autotest (llsc). Option to run cache test instead of booting' \
 			CONFIG_IA64_SGI_AUTOTEST
-	define_bool CONFIG_DEVFS_FS y
-	if [ "$CONFIG_DEVFS_FS" = "y" ]; then
-	  bool '    Enable DEVFS Debug Code' CONFIG_DEVFS_DEBUG
-	fi
 	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL
 	define_bool CONFIG_DISCONTIGMEM y
 	define_bool CONFIG_IA64_MCA y
@@ -107,21 +106,25 @@
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+  define_bool CONFIG_ACPI y
+  define_bool CONFIG_ACPI_EFI y
+  define_bool CONFIG_ACPI_INTERPRETER y
+  define_bool CONFIG_ACPI_KERNEL_CONFIG y
 
-source drivers/acpi/Config.in
-
-bool 'PCI support' CONFIG_PCI
-source drivers/pci/Config.in
+  source drivers/acpi/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
+  bool 'PCI support' CONFIG_PCI
+  source drivers/pci/Config.in
 
-source drivers/parport/Config.in
+  bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+  if [ "$CONFIG_HOTPLUG" = "y" ]; then
+     source drivers/hotplug/Config.in
+     source drivers/pcmcia/Config.in
+  else
+     define_bool CONFIG_PCMCIA n
+  fi
 
+  source drivers/parport/Config.in
 fi # !HP_SIM
 
 endmenu
@@ -131,28 +134,38 @@
 fi
 
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+  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
+  source drivers/message/fusion/Config.in
 
-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
-
-mainmenu_option next_comment
-comment 'ATA/IDE/MFM/RLL support'
-
-tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+  mainmenu_option next_comment
+  comment 'ATA/IDE/MFM/RLL support'
 
-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
+  tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
 
-fi # !HP_SIM
+  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
+else # HP_SIM
+  mainmenu_option next_comment
+  comment 'Block devices'
+  tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+  dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
+
+  tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+  if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
+    int '  Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
+  fi
+  endmenu
+fi # HP_SIM
 
 mainmenu_option next_comment
 comment 'SCSI support'
@@ -164,43 +177,37 @@
 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
+    mainmenu_option next_comment
+    comment 'Network device support'
+
+    bool 'Network device support' CONFIG_NETDEVICES
+    if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+    fi
+    endmenu
+  fi
+
+  source net/ax25/Config.in
 
-if [ "$CONFIG_NET" = "y" ]; then
   mainmenu_option next_comment
-  comment 'Network device support'
+  comment 'ISDN subsystem'
 
-  bool 'Network device support' CONFIG_NETDEVICES
-  if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    source drivers/net/Config.in
+  tristate 'ISDN support' CONFIG_ISDN
+  if [ "$CONFIG_ISDN" != "n" ]; then
+    source drivers/isdn/Config.in
   fi
   endmenu
-fi
-
-source net/ax25/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 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
-
-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 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
 
+  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 # !HP_SIM
 
 #
@@ -227,24 +234,22 @@
 fi
 
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; 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
-
-source drivers/usb/Config.in
+  tristate 'Sound card support' CONFIG_SOUND
+  if [ "$CONFIG_SOUND" != "n" ]; then
+    source drivers/sound/Config.in
+  fi
+  endmenu
 
-source lib/Config.in
+  source drivers/usb/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   source net/bluetooth/Config.in
-fi
+  source lib/Config.in
 
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+     source net/bluetooth/Config.in
+  fi
 fi # !HP_SIM
 
 if [ "$CONFIG_IA64_HP_SIM" != "n" -o "$CONFIG_IA64_GENERIC" != "n" ]; then
@@ -273,7 +278,14 @@
    bool '  Disable VHPT' CONFIG_DISABLE_VHPT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
 
-   bool '  Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
+   bool '  Early printk support' CONFIG_IA64_EARLY_PRINTK
+   if [ "$CONFIG_IA64_EARLY_PRINTK" != "n" ]; then
+      bool '    Early printk on MMIO serial port' CONFIG_IA64_EARLY_PRINTK_UART
+      if [ "$CONFIG_IA64_EARLY_PRINTK_UART" != "n" ]; then
+         hex '      UART MMIO base address' CONFIG_IA64_EARLY_PRINTK_UART_BASE 0
+      fi
+      bool '    Early printk on VGA' CONFIG_IA64_EARLY_PRINTK_VGA
+   fi
    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 -urN linux-2.4.20-pre6/arch/ia64/defconfig linux-2.4.20-pre7/arch/ia64/defconfig
--- linux-2.4.20-pre6/arch/ia64/defconfig	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/defconfig	Thu Sep 12 20:01:39 2002
@@ -24,21 +24,18 @@
 # 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_GENERIC=y
+# CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_HP_ZX1 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_VIRTUAL_MEM_MAP=y
 CONFIG_IA64_BRL_EMU=y
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
@@ -56,15 +53,27 @@
 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=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+
+#
+# ACPI Support
+#
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
 # 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_FAN is not set
+# CONFIG_ACPI_PROCESSOR is not set
 # CONFIG_ACPI_THERMAL is not set
+# CONFIG_ACPI_DEBUG is not set
 CONFIG_PCI=y
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
@@ -80,7 +89,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=y
 CONFIG_UNIX=y
@@ -90,6 +99,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 is not set
 # CONFIG_IPV6 is not set
@@ -102,6 +112,11 @@
 #
 # 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
@@ -119,6 +134,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -137,13 +157,20 @@
 # 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
 
 #
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
 # I2O device support
 #
 # CONFIG_I2O is not set
@@ -166,6 +193,15 @@
 # CONFIG_BLK_DEV_LVM is not set
 
 #
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_BOOT=y
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
 # ATA/IDE/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -182,6 +218,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
@@ -196,6 +233,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -207,12 +245,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 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
@@ -220,6 +261,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
@@ -278,8 +320,12 @@
 # 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_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+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
@@ -299,9 +345,11 @@
 # 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_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -331,6 +379,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)
@@ -340,7 +389,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
@@ -353,7 +401,10 @@
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_TULIP 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
@@ -369,6 +420,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
@@ -382,12 +434,15 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_NET_BROADCOM is not set
 # CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+CONFIG_E1000=y
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+CONFIG_TIGON3=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -445,8 +500,9 @@
 CONFIG_VT_CONSOLE=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_ACPI is not set
+CONFIG_SERIAL_HCDP=y
 # CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_ACPI is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -464,6 +520,7 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -519,16 +576,20 @@
 # CONFIG_FTAPE is not set
 CONFIG_AGP=y
 # CONFIG_AGP_INTEL is not set
-CONFIG_AGP_I460=y
 # CONFIG_AGP_I810 is not set
 # CONFIG_AGP_VIA is not set
 # CONFIG_AGP_AMD is not set
 # CONFIG_AGP_SIS is not set
 # CONFIG_AGP_ALI is not set
 # CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_I460=y
+CONFIG_AGP_HP_ZX1=y
 CONFIG_DRM=y
-# CONFIG_DRM_NEW is not set
 CONFIG_DRM_OLD=y
+
+#
+# DRM 4.0 drivers
+#
 CONFIG_DRM40_TDFX=y
 # CONFIG_DRM40_GAMMA is not set
 # CONFIG_DRM40_R128 is not set
@@ -607,7 +668,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=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -671,12 +732,11 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_DEVFS_GUID 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_EFI_PARTITION=y
 # CONFIG_SMB_NLS is not set
 CONFIG_NLS=y
 
@@ -705,6 +765,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 is not set
 # CONFIG_NLS_ISO8859_2 is not set
@@ -737,6 +798,7 @@
 CONFIG_SOUND=y
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_EMU10K1 is not set
 # CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
@@ -771,8 +833,9 @@
 # CONFIG_USB_LONG_TIMEOUT is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
+CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_UHCI=m
 # CONFIG_USB_UHCI_ALT is not set
 # CONFIG_USB_OHCI is not set
@@ -781,6 +844,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 is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -798,6 +862,7 @@
 # USB Human Interface Devices (HID)
 #
 CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB_KBD=m
 CONFIG_USB_MOUSE=m
@@ -819,6 +884,8 @@
 # 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
 
@@ -826,6 +893,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
@@ -847,6 +915,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
@@ -860,6 +929,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
@@ -869,6 +939,8 @@
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -876,6 +948,13 @@
 # CONFIG_BLUEZ is not set
 
 #
+# Simulated drivers
+#
+# CONFIG_SIMETH is not set
+# CONFIG_SIM_SERIAL is not set
+# CONFIG_SCSI_SIM is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_IA64_GRANULE_16MB is not set
@@ -885,6 +964,9 @@
 # CONFIG_DISABLE_VHPT is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_IA64_EARLY_PRINTK=y
+CONFIG_IA64_EARLY_PRINTK_UART=y
+CONFIG_IA64_EARLY_PRINTK_UART_BASE=0
+# CONFIG_IA64_EARLY_PRINTK_VGA is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_IA64_DEBUG_CMPXCHG is not set
diff -urN linux-2.4.20-pre6/arch/ia64/dig/setup.c linux-2.4.20-pre7/arch/ia64/dig/setup.c
--- linux-2.4.20-pre6/arch/ia64/dig/setup.c	Thu Apr  5 12:51:47 2001
+++ linux-2.4.20-pre7/arch/ia64/dig/setup.c	Thu Sep 12 20:01:39 2002
@@ -33,8 +33,7 @@
  * is sufficient (the IDE driver will autodetect the drive geometry).
  */
 char drive_info[4*16];
-
-unsigned char aux_device_present = 0xaa;	/* XXX remove this when legacy I/O is gone */
+extern int pcat_compat;
 
 void __init
 dig_setup (char **cmdline_p)
@@ -81,13 +80,7 @@
 	screen_info.orig_video_ega_bx = 3;	/* XXX fake */
 }
 
-void
+void __init
 dig_irq_init (void)
 {
-	/*
-	 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
-	 * enabled.
-	 */
-	outb(0xff, 0xA1);
-	outb(0xff, 0x21);
 }
diff -urN linux-2.4.20-pre6/arch/ia64/hp/Makefile linux-2.4.20-pre7/arch/ia64/hp/Makefile
--- linux-2.4.20-pre6/arch/ia64/hp/Makefile	Thu Jan  4 12:50:17 2001
+++ linux-2.4.20-pre7/arch/ia64/hp/Makefile	Thu Sep 12 20:01:39 2002
@@ -1,17 +1,15 @@
-#
-# ia64/platform/hp/Makefile
-#
-# Copyright (C) 1999 Silicon Graphics, Inc.
-# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
-#
+# arch/ia64/hp/Makefile
+# Copyright (c) 2002 Matthew Wilcox for Hewlett Packard
 
-all: hp.a
+ALL_SUB_DIRS := sim zx1 common
 
-O_TARGET := hp.a
+O_TARGET := hp.o
 
-obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
-obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
+subdir-$(CONFIG_IA64_GENERIC) += $(ALL_SUB_DIRS)
+subdir-$(CONFIG_IA64_HP_SIM) += sim
+subdir-$(CONFIG_IA64_HP_ZX1) += zx1 common
 
-clean::
+SUB_DIRS := $(subdir-y)
+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/ia64/hp/common/Makefile linux-2.4.20-pre7/arch/ia64/hp/common/Makefile
--- linux-2.4.20-pre6/arch/ia64/hp/common/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/common/Makefile	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,14 @@
+#
+# ia64/platform/hp/common/Makefile
+#
+# Copyright (C) 2002 Hewlett Packard
+# Copyright (C) Alex Williamson (alex_williamson@hp.com)
+#
+
+O_TARGET := common.o
+
+export-objs := sba_iommu.o
+
+obj-y := sba_iommu.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/ia64/hp/common/sba_iommu.c linux-2.4.20-pre7/arch/ia64/hp/common/sba_iommu.c
--- linux-2.4.20-pre6/arch/ia64/hp/common/sba_iommu.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/common/sba_iommu.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,1867 @@
+/*
+**  IA64 System Bus Adapter (SBA) I/O MMU manager
+**
+**	(c) Copyright 2002 Alex Williamson
+**	(c) Copyright 2002 Hewlett-Packard Company
+**
+**	Portions (c) 2000 Grant Grundler (from parisc I/O MMU code)
+**	Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU 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.
+**
+**
+** This module initializes the IOC (I/O Controller) found on HP
+** McKinley machines and their successors.
+**
+*/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
+
+#include <asm/delay.h>		/* ia64_get_itc() */
+#include <asm/io.h>
+#include <asm/page.h>		/* PAGE_OFFSET */
+
+
+#define PFX "IOC: "
+
+#define ALLOW_IOV_BYPASS
+#define ENABLE_MARK_CLEAN
+/*
+** The number of debug flags is a clue - this code is fragile.
+*/
+#undef DEBUG_SBA_INIT
+#undef DEBUG_SBA_RUN
+#undef DEBUG_SBA_RUN_SG
+#undef DEBUG_SBA_RESOURCE
+#undef ASSERT_PDIR_SANITY
+#undef DEBUG_LARGE_SG_ENTRIES
+#undef DEBUG_BYPASS
+
+#define SBA_INLINE	__inline__
+/* #define SBA_INLINE */
+
+#ifdef DEBUG_SBA_INIT
+#define DBG_INIT(x...)	printk(x)
+#else
+#define DBG_INIT(x...)
+#endif
+
+#ifdef DEBUG_SBA_RUN
+#define DBG_RUN(x...)	printk(x)
+#else
+#define DBG_RUN(x...)
+#endif
+
+#ifdef DEBUG_SBA_RUN_SG
+#define DBG_RUN_SG(x...)	printk(x)
+#else
+#define DBG_RUN_SG(x...)
+#endif
+
+
+#ifdef DEBUG_SBA_RESOURCE
+#define DBG_RES(x...)	printk(x)
+#else
+#define DBG_RES(x...)
+#endif
+
+#ifdef DEBUG_BYPASS
+#define DBG_BYPASS(x...)	printk(x)
+#else
+#define DBG_BYPASS(x...)
+#endif
+
+#ifdef ASSERT_PDIR_SANITY
+#define ASSERT(expr) \
+        if(!(expr)) { \
+                printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
+                panic(#expr); \
+        }
+#else
+#define ASSERT(expr)
+#endif
+
+/*
+** The number of pdir entries to "free" before issueing
+** a read to PCOM register to flush out PCOM writes.
+** Interacts with allocation granularity (ie 4 or 8 entries
+** allocated and free'd/purged at a time might make this
+** less interesting).
+*/
+#define DELAYED_RESOURCE_CNT	16
+
+#define DEFAULT_DMA_HINT_REG	0
+
+#define ZX1_IOC_ID	((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
+#define REO_IOC_ID	((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
+
+#define ZX1_IOC_OFFSET	0x1000	/* ACPI reports SBA, we want IOC */
+
+#define IOC_FUNC_ID	0x000
+#define IOC_FCLASS	0x008	/* function class, bist, header, rev... */
+#define IOC_IBASE	0x300	/* IO TLB */
+#define IOC_IMASK	0x308
+#define IOC_PCOM	0x310
+#define IOC_TCNFG	0x318
+#define IOC_PDIR_BASE	0x320
+
+/* AGP GART driver looks for this */
+#define ZX1_SBA_IOMMU_COOKIE	0x0000badbadc0ffeeUL
+
+/*
+** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
+** It's safer (avoid memory corruption) to keep DMA page mappings
+** equivalently sized to VM PAGE_SIZE.
+**
+** We really can't avoid generating a new mapping for each
+** page since the Virtual Coherence Index has to be generated
+** and updated for each page.
+**
+** IOVP_SIZE could only be greater than PAGE_SIZE if we are
+** confident the drivers really only touch the next physical
+** page iff that driver instance owns it.
+*/
+#define IOVP_SIZE	PAGE_SIZE
+#define IOVP_SHIFT	PAGE_SHIFT
+#define IOVP_MASK	PAGE_MASK
+
+struct ioc {
+	void		*ioc_hpa;	/* I/O MMU base address */
+	char		*res_map;	/* resource map, bit == pdir entry */
+	u64		*pdir_base;	/* physical base address */
+	unsigned long	ibase;		/* pdir IOV Space base */
+	unsigned long	imask;		/* pdir IOV Space mask */
+
+	unsigned long	*res_hint;	/* next avail IOVP - circular search */
+	spinlock_t	res_lock;
+	unsigned long	hint_mask_pdir;	/* bits used for DMA hints */
+	unsigned int	res_bitshift;	/* from the RIGHT! */
+	unsigned int	res_size;	/* size of resource map in bytes */
+	unsigned int	hint_shift_pdir;
+	unsigned long	dma_mask;
+#if DELAYED_RESOURCE_CNT > 0
+	int saved_cnt;
+	struct sba_dma_pair {
+		dma_addr_t	iova;
+		size_t		size;
+	} saved[DELAYED_RESOURCE_CNT];
+#endif
+
+#ifdef CONFIG_PROC_FS
+#define SBA_SEARCH_SAMPLE	0x100
+	unsigned long avg_search[SBA_SEARCH_SAMPLE];
+	unsigned long avg_idx;	/* current index into avg_search */
+	unsigned long used_pages;
+	unsigned long msingle_calls;
+	unsigned long msingle_pages;
+	unsigned long msg_calls;
+	unsigned long msg_pages;
+	unsigned long usingle_calls;
+	unsigned long usingle_pages;
+	unsigned long usg_calls;
+	unsigned long usg_pages;
+#ifdef ALLOW_IOV_BYPASS
+	unsigned long msingle_bypass;
+	unsigned long usingle_bypass;
+	unsigned long msg_bypass;
+#endif
+#endif
+
+	/* Stuff we don't need in performance path */
+	struct ioc	*next;		/* list of IOC's in system */
+	acpi_handle	handle;		/* for multiple IOC's */
+	const char 	*name;
+	unsigned int	func_id;
+	unsigned int	rev;		/* HW revision of chip */
+	u32		iov_size;
+	unsigned int	pdir_size;	/* in bytes, determined by IOV Space size */
+	struct pci_dev	*sac_only_dev;
+};
+
+static struct ioc *ioc_list;
+static int reserve_sba_gart = 1;
+
+#define sba_sg_iova(sg) (sg->address)
+#define sba_sg_len(sg) (sg->length)
+#define sba_sg_buffer(sg) (sg->orig_address)
+
+#define GET_IOC(dev)	((struct ioc *) PCI_CONTROLLER(dev)->iommu)
+
+/*
+** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up
+** (or rather not merge) DMA's into managable chunks.
+** On parisc, this is more of the software/tuning constraint
+** rather than the HW. I/O MMU allocation alogorithms can be
+** faster with smaller size is (to some degree).
+*/
+#define DMA_CHUNK_SIZE  (BITS_PER_LONG*PAGE_SIZE)
+
+#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
+
+/************************************
+** SBA register read and write support
+**
+** BE WARNED: register writes are posted.
+**  (ie follow writes which must reach HW with a read)
+**
+*/
+#define READ_REG(addr)       __raw_readq(addr)
+#define WRITE_REG(val, addr) __raw_writeq(val, addr)
+
+#ifdef DEBUG_SBA_INIT
+
+/**
+ * sba_dump_tlb - debugging only - print IOMMU operating parameters
+ * @hpa: base address of the IOMMU
+ *
+ * Print the size/location of the IO MMU PDIR.
+ */
+static void
+sba_dump_tlb(char *hpa)
+{
+	DBG_INIT("IO TLB at 0x%p\n", (void *)hpa);
+	DBG_INIT("IOC_IBASE    : %016lx\n", READ_REG(hpa+IOC_IBASE));
+	DBG_INIT("IOC_IMASK    : %016lx\n", READ_REG(hpa+IOC_IMASK));
+	DBG_INIT("IOC_TCNFG    : %016lx\n", READ_REG(hpa+IOC_TCNFG));
+	DBG_INIT("IOC_PDIR_BASE: %016lx\n", READ_REG(hpa+IOC_PDIR_BASE));
+	DBG_INIT("\n");
+}
+#endif
+
+
+#ifdef ASSERT_PDIR_SANITY
+
+/**
+ * sba_dump_pdir_entry - debugging only - print one IOMMU PDIR entry
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ * @pide: pdir index.
+ *
+ * Print one entry of the IO MMU PDIR in human readable form.
+ */
+static void
+sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
+{
+	/* start printing from lowest pde in rval */
+	u64 *ptr = &(ioc->pdir_base[pide  & ~(BITS_PER_LONG - 1)]);
+	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
+	uint rcnt;
+
+	/* printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", */
+	printk("SBA: %s rp %p bit %d rval 0x%lx\n",
+		 msg, rptr, pide & (BITS_PER_LONG - 1), *rptr);
+
+	rcnt = 0;
+	while (rcnt < BITS_PER_LONG) {
+		printk("%s %2d %p %016Lx\n",
+			(rcnt == (pide & (BITS_PER_LONG - 1)))
+				? "    -->" : "       ",
+			rcnt, ptr, *ptr );
+		rcnt++;
+		ptr++;
+	}
+	printk("%s", msg);
+}
+
+
+/**
+ * sba_check_pdir - debugging only - consistency checker
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @msg: text to print ont the output line.
+ *
+ * Verify the resource map and pdir state is consistent
+ */
+static int
+sba_check_pdir(struct ioc *ioc, char *msg)
+{
+	u64 *rptr_end = (u64 *) &(ioc->res_map[ioc->res_size]);
+	u64 *rptr = (u64 *) ioc->res_map;	/* resource map ptr */
+	u64 *pptr = ioc->pdir_base;	/* pdir ptr */
+	uint pide = 0;
+
+	while (rptr < rptr_end) {
+		u64 rval;
+		int rcnt; /* number of bits we might check */
+
+		rval = *rptr;
+		rcnt = 64;
+
+		while (rcnt) {
+			/* Get last byte and highest bit from that */
+			u32 pde = ((u32)((*pptr >> (63)) & 0x1));
+			if ((rval & 0x1) ^ pde)
+			{
+				/*
+				** BUMMER!  -- res_map != pdir --
+				** Dump rval and matching pdir entries
+				*/
+				sba_dump_pdir_entry(ioc, msg, pide);
+				return(1);
+			}
+			rcnt--;
+			rval >>= 1;	/* try the next bit */
+			pptr++;
+			pide++;
+		}
+		rptr++;	/* look at next word of res_map */
+	}
+	/* It'd be nice if we always got here :^) */
+	return 0;
+}
+
+
+/**
+ * sba_dump_sg - debugging only - print Scatter-Gather list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg: head of the SG list
+ * @nents: number of entries in SG list
+ *
+ * print the SG list so we can verify it's correct by hand.
+ */
+static void
+sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
+{
+	while (nents-- > 0) {
+		printk(" %d : %08lx/%05x %p\n",
+				nents,
+				(unsigned long) sba_sg_iova(startsg),
+				sba_sg_len(startsg),
+				sba_sg_buffer(startsg));
+		startsg++;
+	}
+}
+static void
+sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
+{
+	struct scatterlist *the_sg = startsg;
+	int the_nents = nents;
+
+	while (the_nents-- > 0) {
+		if (sba_sg_buffer(the_sg) == 0x0UL)
+			sba_dump_sg(NULL, startsg, nents);
+		the_sg++;
+	}
+}
+
+#endif /* ASSERT_PDIR_SANITY */
+
+
+
+
+/**************************************************************
+*
+*   I/O Pdir Resource Management
+*
+*   Bits set in the resource map are in use.
+*   Each bit can represent a number of pages.
+*   LSbs represent lower addresses (IOVA's).
+*
+***************************************************************/
+#define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
+
+/* Convert from IOVP to IOVA and vice versa. */
+#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir)))
+#define SBA_IOVP(ioc,iova) (((iova) & ioc->hint_mask_pdir) & ~(ioc->ibase))
+
+/* FIXME : review these macros to verify correctness and usage */
+#define PDIR_INDEX(iovp)   ((iovp)>>IOVP_SHIFT)
+
+#define RESMAP_MASK(n)    ~(~0UL << (n))
+#define RESMAP_IDX_MASK   (sizeof(unsigned long) - 1)
+
+
+/**
+ * sba_search_bitmap - find free space in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @bits_wanted: number of entries we need.
+ *
+ * Find consecutive free bits in resource bitmap.
+ * Each bit represents one entry in the IO Pdir.
+ * Cool perf optimization: search for log2(size) bits at a time.
+ */
+static SBA_INLINE unsigned long
+sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted)
+{
+	unsigned long *res_ptr = ioc->res_hint;
+	unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
+	unsigned long pide = ~0UL;
+
+	ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
+	ASSERT(res_ptr < res_end);
+	if (bits_wanted > (BITS_PER_LONG/2)) {
+		/* Search word at a time - no mask needed */
+		for(; res_ptr < res_end; ++res_ptr) {
+			if (*res_ptr == 0) {
+				*res_ptr = RESMAP_MASK(bits_wanted);
+				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+				pide <<= 3;	/* convert to bit address */
+				break;
+			}
+		}
+		/* point to the next word on next pass */
+		res_ptr++;
+		ioc->res_bitshift = 0;
+	} else {
+		/*
+		** Search the resource bit map on well-aligned values.
+		** "o" is the alignment.
+		** We need the alignment to invalidate I/O TLB using
+		** SBA HW features in the unmap path.
+		*/
+		unsigned long o = 1 << get_order(bits_wanted << PAGE_SHIFT);
+		uint bitshiftcnt = ROUNDUP(ioc->res_bitshift, o);
+		unsigned long mask;
+
+		if (bitshiftcnt >= BITS_PER_LONG) {
+			bitshiftcnt = 0;
+			res_ptr++;
+		}
+		mask = RESMAP_MASK(bits_wanted) << bitshiftcnt;
+
+		DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr);
+		while(res_ptr < res_end)
+		{ 
+			DBG_RES("    %p %lx %lx\n", res_ptr, mask, *res_ptr);
+			ASSERT(0 != mask);
+			if(0 == ((*res_ptr) & mask)) {
+				*res_ptr |= mask;     /* mark resources busy! */
+				pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+				pide <<= 3;	/* convert to bit address */
+				pide += bitshiftcnt;
+				break;
+			}
+			mask <<= o;
+			bitshiftcnt += o;
+			if (0 == mask) {
+				mask = RESMAP_MASK(bits_wanted);
+				bitshiftcnt=0;
+				res_ptr++;
+			}
+		}
+		/* look in the same word on the next pass */
+		ioc->res_bitshift = bitshiftcnt + bits_wanted;
+	}
+
+	/* wrapped ? */
+	if (res_end <= res_ptr) {
+		ioc->res_hint = (unsigned long *) ioc->res_map;
+		ioc->res_bitshift = 0;
+	} else {
+		ioc->res_hint = res_ptr;
+	}
+	return (pide);
+}
+
+
+/**
+ * sba_alloc_range - find free bits and mark them in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @size: number of bytes to create a mapping for
+ *
+ * Given a size, find consecutive unmarked and then mark those bits in the
+ * resource bit map.
+ */
+static int
+sba_alloc_range(struct ioc *ioc, size_t size)
+{
+	unsigned int pages_needed = size >> IOVP_SHIFT;
+#ifdef CONFIG_PROC_FS
+	unsigned long itc_start = ia64_get_itc();
+#endif
+	unsigned long pide;
+
+	ASSERT(pages_needed);
+	ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(pages_needed <= BITS_PER_LONG);
+	ASSERT(0 == (size & ~IOVP_MASK));
+
+	/*
+	** "seek and ye shall find"...praying never hurts either...
+	*/
+
+	pide = sba_search_bitmap(ioc, pages_needed);
+	if (pide >= (ioc->res_size << 3)) {
+		pide = sba_search_bitmap(ioc, pages_needed);
+		if (pide >= (ioc->res_size << 3))
+			panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
+	}
+
+#ifdef ASSERT_PDIR_SANITY
+	/* verify the first enable bit is clear */
+	if(0x00 != ((u8 *) ioc->pdir_base)[pide*sizeof(u64) + 7]) {
+		sba_dump_pdir_entry(ioc, "sba_search_bitmap() botched it?", pide);
+	}
+#endif
+
+	DBG_RES("%s(%x) %d -> %lx hint %x/%x\n",
+		__FUNCTION__, size, pages_needed, pide,
+		(uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map),
+		ioc->res_bitshift );
+
+#ifdef CONFIG_PROC_FS
+	{
+		unsigned long itc_end = ia64_get_itc();
+		unsigned long tmp = itc_end - itc_start;
+		/* check for roll over */
+		itc_start = (itc_end < itc_start) ?  -(tmp) : (tmp);
+	}
+	ioc->avg_search[ioc->avg_idx++] = itc_start;
+	ioc->avg_idx &= SBA_SEARCH_SAMPLE - 1;
+
+	ioc->used_pages += pages_needed;
+#endif
+
+	return (pide);
+}
+
+
+/**
+ * sba_free_range - unmark bits in IO PDIR resource bitmap
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova: IO virtual address which was previously allocated.
+ * @size: number of bytes to create a mapping for
+ *
+ * clear bits in the ioc's resource map
+ */
+static SBA_INLINE void
+sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size)
+{
+	unsigned long iovp = SBA_IOVP(ioc, iova);
+	unsigned int pide = PDIR_INDEX(iovp);
+	unsigned int ridx = pide >> 3;	/* convert bit to byte address */
+	unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
+
+	int bits_not_wanted = size >> IOVP_SHIFT;
+
+	/* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
+	unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));
+
+	DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n",
+		__FUNCTION__, (uint) iova, size,
+		bits_not_wanted, m, pide, res_ptr, *res_ptr);
+
+#ifdef CONFIG_PROC_FS
+	ioc->used_pages -= bits_not_wanted;
+#endif
+
+	ASSERT(m != 0);
+	ASSERT(bits_not_wanted);
+	ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+	ASSERT(bits_not_wanted <= BITS_PER_LONG);
+	ASSERT((*res_ptr & m) == m); /* verify same bits are set */
+	*res_ptr &= ~m;
+}
+
+
+/**************************************************************
+*
+*   "Dynamic DMA Mapping" support (aka "Coherent I/O")
+*
+***************************************************************/
+
+#define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
+
+
+/**
+ * sba_io_pdir_entry - fill in one IO PDIR entry
+ * @pdir_ptr:  pointer to IO PDIR entry
+ * @vba: Virtual CPU address of buffer to map
+ *
+ * SBA Mapping Routine
+ *
+ * Given a virtual address (vba, arg1) sba_io_pdir_entry()
+ * loads the I/O PDIR entry pointed to by pdir_ptr (arg0).
+ * Each IO Pdir entry consists of 8 bytes as shown below
+ * (LSB == bit 0):
+ *
+ *  63                    40                                 11    7        0
+ * +-+---------------------+----------------------------------+----+--------+
+ * |V|        U            |            PPN[39:12]            | U  |   FF   |
+ * +-+---------------------+----------------------------------+----+--------+
+ *
+ *  V  == Valid Bit
+ *  U  == Unused
+ * PPN == Physical Page Number
+ *
+ * The physical address fields are filled with the results of virt_to_phys()
+ * on the vba.
+ */
+
+#if 1
+#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x8000000000000000ULL)
+#else
+void SBA_INLINE
+sba_io_pdir_entry(u64 *pdir_ptr, unsigned long vba)
+{
+	*pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x80000000000000FFULL);
+}
+#endif
+
+#ifdef ENABLE_MARK_CLEAN
+/**
+ * Since DMA is i-cache coherent, any (complete) pages that were written via
+ * DMA can be marked as "clean" so that update_mmu_cache() doesn't have to
+ * flush them when they get mapped into an executable vm-area.
+ */
+static void
+mark_clean (void *addr, size_t size)
+{
+	unsigned long pg_addr, end;
+
+	pg_addr = PAGE_ALIGN((unsigned long) addr);
+	end = (unsigned long) addr + size;
+	while (pg_addr + PAGE_SIZE <= end) {
+		struct page *page = virt_to_page(pg_addr);
+		set_bit(PG_arch_1, &page->flags);
+		pg_addr += PAGE_SIZE;
+	}
+}
+#endif
+
+/**
+ * sba_mark_invalid - invalidate one or more IO PDIR entries
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @iova:  IO Virtual Address mapped earlier
+ * @byte_cnt:  number of bytes this mapping covers.
+ *
+ * Marking the IO PDIR entry(ies) as Invalid and invalidate
+ * corresponding IO TLB entry. The PCOM (Purge Command Register)
+ * is to purge stale entries in the IO TLB when unmapping entries.
+ *
+ * The PCOM register supports purging of multiple pages, with a minium
+ * of 1 page and a maximum of 2GB. Hardware requires the address be
+ * aligned to the size of the range being purged. The size of the range
+ * must be a power of 2. The "Cool perf optimization" in the
+ * allocation routine helps keep that true.
+ */
+static SBA_INLINE void
+sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
+{
+	u32 iovp = (u32) SBA_IOVP(ioc,iova);
+
+	int off = PDIR_INDEX(iovp);
+
+	/* Must be non-zero and rounded up */
+	ASSERT(byte_cnt > 0);
+	ASSERT(0 == (byte_cnt & ~IOVP_MASK));
+
+#ifdef ASSERT_PDIR_SANITY
+	/* Assert first pdir entry is set */
+	if (!(ioc->pdir_base[off] >> 60)) {
+		sba_dump_pdir_entry(ioc,"sba_mark_invalid()", PDIR_INDEX(iovp));
+	}
+#endif
+
+	if (byte_cnt <= IOVP_SIZE)
+	{
+		ASSERT(off < ioc->pdir_size);
+
+		iovp |= IOVP_SHIFT;     /* set "size" field for PCOM */
+
+		/*
+		** clear I/O PDIR entry "valid" bit
+		** Do NOT clear the rest - save it for debugging.
+		** We should only clear bits that have previously
+		** been enabled.
+		*/
+		ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
+	} else {
+		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
+
+		iovp |= t;
+		ASSERT(t <= 31);   /* 2GB! Max value of "size" field */
+
+		do {
+			/* verify this pdir entry is enabled */
+			ASSERT(ioc->pdir_base[off]  >> 63);
+			/* clear I/O Pdir entry "valid" bit first */
+			ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
+			off++;
+			byte_cnt -= IOVP_SIZE;
+		} while (byte_cnt > 0);
+	}
+
+	WRITE_REG(iovp, ioc->ioc_hpa+IOC_PCOM);
+}
+
+/**
+ * sba_map_single - map one buffer and return IOVA for DMA
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @addr:  driver buffer to map.
+ * @size:  number of bytes to map in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+dma_addr_t
+sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+{
+	struct ioc *ioc;
+	unsigned long flags; 
+	dma_addr_t iovp;
+	dma_addr_t offset;
+	u64 *pdir_start;
+	int pide;
+#ifdef ALLOW_IOV_BYPASS
+	unsigned long pci_addr = virt_to_phys(addr);
+#endif
+
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef ALLOW_IOV_BYPASS
+	/*
+ 	** Check if the PCI device can DMA to ptr... if so, just return ptr
+ 	*/
+	if ((pci_addr & ~dev->dma_mask) == 0) {
+		/*
+ 		** Device is bit capable of DMA'ing to the buffer...
+		** just return the PCI address of ptr
+ 		*/
+#ifdef CONFIG_PROC_FS
+		spin_lock_irqsave(&ioc->res_lock, flags);
+		ioc->msingle_bypass++;
+		spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+		DBG_BYPASS("sba_map_single() bypass mask/addr: 0x%lx/0x%lx\n",
+		           dev->dma_mask, pci_addr);
+		return pci_addr;
+	}
+#endif
+
+	ASSERT(size > 0);
+	ASSERT(size <= DMA_CHUNK_SIZE);
+
+	/* save offset bits */
+	offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
+
+	/* round up to nearest IOVP_SIZE */
+	size = (size + offset + ~IOVP_MASK) & IOVP_MASK;
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check before sba_map_single()"))
+		panic("Sanity check failed");
+#endif
+
+#ifdef CONFIG_PROC_FS
+	ioc->msingle_calls++;
+	ioc->msingle_pages += size >> IOVP_SHIFT;
+#endif
+	pide = sba_alloc_range(ioc, size);
+	iovp = (dma_addr_t) pide << IOVP_SHIFT;
+
+	DBG_RUN("%s() 0x%p -> 0x%lx\n",
+		__FUNCTION__, addr, (long) iovp | offset);
+
+	pdir_start = &(ioc->pdir_base[pide]);
+
+	while (size > 0) {
+		ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
+		sba_io_pdir_entry(pdir_start, (unsigned long) addr);
+
+		DBG_RUN("     pdir 0x%p %lx\n", pdir_start, *pdir_start);
+
+		addr += IOVP_SIZE;
+		size -= IOVP_SIZE;
+		pdir_start++;
+	}
+	/* form complete address */
+#ifdef ASSERT_PDIR_SANITY
+	sba_check_pdir(ioc,"Check after sba_map_single()");
+#endif
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+	return SBA_IOVA(ioc, iovp, offset, DEFAULT_DMA_HINT_REG);
+}
+
+/**
+ * sba_unmap_single - unmap one IOVA and free resources
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @iova:  IOVA of driver buffer previously mapped.
+ * @size:  number of bytes mapped in driver buffer.
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size,
+		int direction)
+{
+	struct ioc *ioc;
+#if DELAYED_RESOURCE_CNT > 0
+	struct sba_dma_pair *d;
+#endif
+	unsigned long flags; 
+	dma_addr_t offset;
+
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef ALLOW_IOV_BYPASS
+	if ((iova & ioc->imask) != ioc->ibase) {
+		/*
+		** Address does not fall w/in IOVA, must be bypassing
+		*/
+#ifdef CONFIG_PROC_FS
+		spin_lock_irqsave(&ioc->res_lock, flags);
+		ioc->usingle_bypass++;
+		spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+		DBG_BYPASS("sba_unmap_single() bypass addr: 0x%lx\n", iova);
+
+#ifdef ENABLE_MARK_CLEAN
+		if (direction == PCI_DMA_FROMDEVICE) {
+			mark_clean(phys_to_virt(iova), size);
+		}
+#endif
+		return;
+	}
+#endif
+	offset = iova & ~IOVP_MASK;
+
+	DBG_RUN("%s() iovp 0x%lx/%x\n",
+		__FUNCTION__, (long) iova, size);
+
+	iova ^= offset;        /* clear offset bits */
+	size += offset;
+	size = ROUNDUP(size, IOVP_SIZE);
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+#ifdef CONFIG_PROC_FS
+	ioc->usingle_calls++;
+	ioc->usingle_pages += size >> IOVP_SHIFT;
+#endif
+
+#if DELAYED_RESOURCE_CNT > 0
+	d = &(ioc->saved[ioc->saved_cnt]);
+	d->iova = iova;
+	d->size = size;
+	if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) {
+		int cnt = ioc->saved_cnt;
+		while (cnt--) {
+			sba_mark_invalid(ioc, d->iova, d->size);
+			sba_free_range(ioc, d->iova, d->size);
+			d--;
+		}
+		ioc->saved_cnt = 0;
+		READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+	}
+#else /* DELAYED_RESOURCE_CNT == 0 */
+	sba_mark_invalid(ioc, iova, size);
+	sba_free_range(ioc, iova, size);
+	READ_REG(ioc->ioc_hpa+IOC_PCOM);	/* flush purges */
+#endif /* DELAYED_RESOURCE_CNT == 0 */
+#ifdef ENABLE_MARK_CLEAN
+	if (direction == PCI_DMA_FROMDEVICE) {
+		u32 iovp = (u32) SBA_IOVP(ioc,iova);
+		int off = PDIR_INDEX(iovp);
+		void *addr;
+
+		if (size <= IOVP_SIZE) {
+			addr = phys_to_virt(ioc->pdir_base[off] &
+					    ~0xE000000000000FFFULL);
+			mark_clean(addr, size);
+		} else {
+			size_t byte_cnt = size;
+
+			do {
+				addr = phys_to_virt(ioc->pdir_base[off] &
+				                    ~0xE000000000000FFFULL);
+				mark_clean(addr, min(byte_cnt, IOVP_SIZE));
+				off++;
+				byte_cnt -= IOVP_SIZE;
+
+			   } while (byte_cnt > 0);
+		}
+	}
+#endif
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	/* XXX REVISIT for 2.5 Linux - need syncdma for zero-copy support.
+	** For Astro based systems this isn't a big deal WRT performance.
+	** As long as 2.4 kernels copyin/copyout data from/to userspace,
+	** we don't need the syncdma. The issue here is I/O MMU cachelines
+	** are *not* coherent in all cases.  May be hwrev dependent.
+	** Need to investigate more.
+	asm volatile("syncdma");	
+	*/
+}
+
+
+/**
+ * sba_alloc_consistent - allocate/map shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @dma_handle:  IOVA of new buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void *
+sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+{
+	struct ioc *ioc;
+	void *ret;
+
+	if (!hwdev) {
+		/* only support PCI */
+		*dma_handle = 0;
+		return 0;
+	}
+
+        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (ret) {
+		memset(ret, 0, size);
+		/*
+		 * REVISIT: if sba_map_single starts needing more
+		 * than dma_mask from the device, this needs to be
+		 * updated.
+		 */
+		ioc = GET_IOC(hwdev);
+		*dma_handle = sba_map_single(ioc->sac_only_dev, ret, size, 0);
+	}
+
+	return ret;
+}
+
+
+/**
+ * sba_free_consistent - free/unmap shared mem for DMA
+ * @hwdev: instance of PCI owned by the driver that's asking.
+ * @size:  number of bytes mapped in driver buffer.
+ * @vaddr:  virtual address IOVA of "consistent" buffer.
+ * @dma_handler:  IO virtual address of "consistent" buffer.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
+		dma_addr_t dma_handle)
+{
+	sba_unmap_single(hwdev, dma_handle, size, 0);
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+
+/*
+** Since 0 is a valid pdir_base index value, can't use that
+** to determine if a value is valid or not. Use a flag to indicate
+** the SG list entry contains a valid pdir index.
+*/
+#define PIDE_FLAG 0x1UL
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+int dump_run_sg = 0;
+#endif
+
+
+/**
+ * sba_fill_pdir - write allocated SG entries into IO PDIR
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * Take preprocessed SG list and write corresponding entries
+ * in the IO PDIR.
+ */
+
+static SBA_INLINE int
+sba_fill_pdir(
+	struct ioc *ioc,
+	struct scatterlist *startsg,
+	int nents)
+{
+	struct scatterlist *dma_sg = startsg;	/* pointer to current DMA */
+	int n_mappings = 0;
+	u64 *pdirp = 0;
+	unsigned long dma_offset = 0;
+
+	dma_sg--;
+	while (nents-- > 0) {
+		int     cnt = sba_sg_len(startsg);
+		sba_sg_len(startsg) = 0;
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+		if (dump_run_sg)
+			printk(" %2d : %08lx/%05x %p\n",
+				nents,
+				(unsigned long) sba_sg_iova(startsg), cnt,
+				sba_sg_buffer(startsg)
+		);
+#else
+		DBG_RUN_SG(" %d : %08lx/%05x %p\n",
+				nents,
+				(unsigned long) sba_sg_iova(startsg), cnt,
+				sba_sg_buffer(startsg)
+		);
+#endif
+		/*
+		** Look for the start of a new DMA stream
+		*/
+		if ((u64)sba_sg_iova(startsg) & PIDE_FLAG) {
+			u32 pide = (u64)sba_sg_iova(startsg) & ~PIDE_FLAG;
+			dma_offset = (unsigned long) pide & ~IOVP_MASK;
+			sba_sg_iova(startsg) = 0;
+			dma_sg++;
+			sba_sg_iova(dma_sg) = (char *)(pide | ioc->ibase);
+			pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
+			n_mappings++;
+		}
+
+		/*
+		** Look for a VCONTIG chunk
+		*/
+		if (cnt) {
+			unsigned long vaddr = (unsigned long) sba_sg_buffer(startsg);
+			ASSERT(pdirp);
+
+			/* Since multiple Vcontig blocks could make up
+			** one DMA stream, *add* cnt to dma_len.
+			*/
+			sba_sg_len(dma_sg) += cnt;
+			cnt += dma_offset;
+			dma_offset=0;	/* only want offset on first chunk */
+			cnt = ROUNDUP(cnt, IOVP_SIZE);
+#ifdef CONFIG_PROC_FS
+			ioc->msg_pages += cnt >> IOVP_SHIFT;
+#endif
+			do {
+				sba_io_pdir_entry(pdirp, vaddr);
+				vaddr += IOVP_SIZE;
+				cnt -= IOVP_SIZE;
+				pdirp++;
+			} while (cnt > 0);
+		}
+		startsg++;
+	}
+#ifdef DEBUG_LARGE_SG_ENTRIES
+	dump_run_sg = 0;
+#endif
+	return(n_mappings);
+}
+
+
+/*
+** Two address ranges are DMA contiguous *iff* "end of prev" and
+** "start of next" are both on a page boundry.
+**
+** (shift left is a quick trick to mask off upper bits)
+*/
+#define DMA_CONTIG(__X, __Y) \
+	(((((unsigned long) __X) | ((unsigned long) __Y)) << (BITS_PER_LONG - PAGE_SHIFT)) == 0UL)
+
+
+/**
+ * sba_coalesce_chunks - preprocess the SG list
+ * @ioc: IO MMU structure which owns the pdir we are interested in.
+ * @startsg:  list of IOVA/size pairs
+ * @nents: number of entries in startsg list
+ *
+ * First pass is to walk the SG list and determine where the breaks are
+ * in the DMA stream. Allocates PDIR entries but does not fill them.
+ * Returns the number of DMA chunks.
+ *
+ * Doing the fill seperate from the coalescing/allocation keeps the
+ * code simpler. Future enhancement could make one pass through
+ * the sglist do both.
+ */
+static SBA_INLINE int
+sba_coalesce_chunks( struct ioc *ioc,
+	struct scatterlist *startsg,
+	int nents)
+{
+	struct scatterlist *vcontig_sg;    /* VCONTIG chunk head */
+	unsigned long vcontig_len;         /* len of VCONTIG chunk */
+	unsigned long vcontig_end;
+	struct scatterlist *dma_sg;        /* next DMA stream head */
+	unsigned long dma_offset, dma_len; /* start/len of DMA stream */
+	int n_mappings = 0;
+
+	while (nents > 0) {
+		unsigned long vaddr = (unsigned long) (startsg->address); 
+
+		/*
+		** Prepare for first/next DMA stream
+		*/
+		dma_sg = vcontig_sg = startsg;
+		dma_len = vcontig_len = vcontig_end = sba_sg_len(startsg);
+		vcontig_end +=  vaddr;
+		dma_offset = vaddr & ~IOVP_MASK;
+
+		/* PARANOID: clear entries */
+		sba_sg_buffer(startsg) = sba_sg_iova(startsg);
+		sba_sg_iova(startsg) = 0;
+		sba_sg_len(startsg) = 0;
+
+		/*
+		** This loop terminates one iteration "early" since
+		** it's always looking one "ahead".
+		*/
+		while (--nents > 0) {
+			unsigned long vaddr;	/* tmp */
+
+			startsg++;
+
+			/* catch brokenness in SCSI layer */
+			ASSERT(startsg->length <= DMA_CHUNK_SIZE);
+
+			/*
+			** First make sure current dma stream won't
+			** exceed DMA_CHUNK_SIZE if we coalesce the
+			** next entry.
+			*/
+			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE)
+				break;
+
+			/*
+			** Then look for virtually contiguous blocks.
+			**
+			** append the next transaction?
+			*/
+			vaddr = (unsigned long) sba_sg_iova(startsg);
+			if  (vcontig_end == vaddr)
+			{
+				vcontig_len += sba_sg_len(startsg);
+				vcontig_end += sba_sg_len(startsg);
+				dma_len     += sba_sg_len(startsg);
+				sba_sg_buffer(startsg) = (char *)vaddr;
+				sba_sg_iova(startsg) = 0;
+				sba_sg_len(startsg) = 0;
+				continue;
+			}
+
+#ifdef DEBUG_LARGE_SG_ENTRIES
+			dump_run_sg = (vcontig_len > IOVP_SIZE);
+#endif
+
+			/*
+			** Not virtually contigous.
+			** Terminate prev chunk.
+			** Start a new chunk.
+			**
+			** Once we start a new VCONTIG chunk, dma_offset
+			** can't change. And we need the offset from the first
+			** chunk - not the last one. Ergo Successive chunks
+			** must start on page boundaries and dove tail
+			** with it's predecessor.
+			*/
+			sba_sg_len(vcontig_sg) = vcontig_len;
+
+			vcontig_sg = startsg;
+			vcontig_len = sba_sg_len(startsg);
+
+			/*
+			** 3) do the entries end/start on page boundaries?
+			**    Don't update vcontig_end until we've checked.
+			*/
+			if (DMA_CONTIG(vcontig_end, vaddr))
+			{
+				vcontig_end = vcontig_len + vaddr;
+				dma_len += vcontig_len;
+				sba_sg_buffer(startsg) = (char *)vaddr;
+				sba_sg_iova(startsg) = 0;
+				continue;
+			} else {
+				break;
+			}
+		}
+
+		/*
+		** End of DMA Stream
+		** Terminate last VCONTIG block.
+		** Allocate space for DMA stream.
+		*/
+		sba_sg_len(vcontig_sg) = vcontig_len;
+		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
+		ASSERT(dma_len <= DMA_CHUNK_SIZE);
+		sba_sg_iova(dma_sg) = (char *) (PIDE_FLAG 
+			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
+			| dma_offset);
+		n_mappings++;
+	}
+
+	return n_mappings;
+}
+
+
+/**
+ * sba_map_sg - map Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
+		int direction)
+{
+	struct ioc *ioc;
+	int coalesced, filled = 0;
+	unsigned long flags;
+#ifdef ALLOW_IOV_BYPASS
+	struct scatterlist *sg;
+#endif
+
+	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef ALLOW_IOV_BYPASS
+	if (dev->dma_mask >= ioc->dma_mask) {
+		for (sg = sglist ; filled < nents ; filled++, sg++){
+			sba_sg_buffer(sg) = sba_sg_iova(sg);
+			sba_sg_iova(sg) = (char *)virt_to_phys(sba_sg_buffer(sg));
+		}
+#ifdef CONFIG_PROC_FS
+		spin_lock_irqsave(&ioc->res_lock, flags);
+		ioc->msg_bypass++;
+		spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+		return filled;
+	}
+#endif
+	/* Fast path single entry scatterlists. */
+	if (nents == 1) {
+		sba_sg_buffer(sglist) = sba_sg_iova(sglist);
+		sba_sg_iova(sglist) = (char *)sba_map_single(dev,
+						sba_sg_buffer(sglist),
+						sba_sg_len(sglist), direction);
+#ifdef CONFIG_PROC_FS
+		/*
+		** Should probably do some stats counting, but trying to
+		** be precise quickly starts wasting CPU time.
+		*/
+#endif
+		return 1;
+	}
+
+	spin_lock_irqsave(&ioc->res_lock, flags);
+
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check before sba_map_sg()"))
+	{
+		sba_dump_sg(ioc, sglist, nents);
+		panic("Check before sba_map_sg()");
+	}
+#endif
+
+#ifdef CONFIG_PROC_FS
+	ioc->msg_calls++;
+#endif
+
+	/*
+	** First coalesce the chunks and allocate I/O pdir space
+	**
+	** If this is one DMA stream, we can properly map using the
+	** correct virtual address associated with each DMA page.
+	** w/o this association, we wouldn't have coherent DMA!
+	** Access to the virtual address is what forces a two pass algorithm.
+	*/
+	coalesced = sba_coalesce_chunks(ioc, sglist, nents);
+ 
+	/*
+	** Program the I/O Pdir
+	**
+	** map the virtual addresses to the I/O Pdir
+	** o dma_address will contain the pdir index
+	** o dma_len will contain the number of bytes to map 
+	** o address contains the virtual address.
+	*/
+	filled = sba_fill_pdir(ioc, sglist, nents);
+
+#ifdef ASSERT_PDIR_SANITY
+	if (sba_check_pdir(ioc,"Check after sba_map_sg()"))
+	{
+		sba_dump_sg(ioc, sglist, nents);
+		panic("Check after sba_map_sg()\n");
+	}
+#endif
+
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+	ASSERT(coalesced == filled);
+	DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+
+	return filled;
+}
+
+
+/**
+ * sba_unmap_sg - unmap Scatter/Gather list
+ * @dev: instance of PCI owned by the driver that's asking.
+ * @sglist:  array of buffer/length pairs
+ * @nents:  number of entries in list
+ * @direction:  R/W or both.
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+void sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
+		int direction)
+{
+	struct ioc *ioc;
+#ifdef ASSERT_PDIR_SANITY
+	unsigned long flags;
+#endif
+
+	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
+		__FUNCTION__, nents, sba_sg_buffer(sglist), sglist->length);
+
+	ioc = GET_IOC(dev);
+	ASSERT(ioc);
+
+#ifdef CONFIG_PROC_FS
+	ioc->usg_calls++;
+#endif
+
+#ifdef ASSERT_PDIR_SANITY
+	spin_lock_irqsave(&ioc->res_lock, flags);
+	sba_check_pdir(ioc,"Check before sba_unmap_sg()");
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+
+	while (sba_sg_len(sglist) && nents--) {
+
+		sba_unmap_single(dev, (dma_addr_t)sba_sg_iova(sglist),
+		                 sba_sg_len(sglist), direction);
+#ifdef CONFIG_PROC_FS
+		/*
+		** This leaves inconsistent data in the stats, but we can't
+		** tell which sg lists were mapped by map_single and which
+		** were coalesced to a single entry.  The stats are fun,
+		** but speed is more important.
+		*/
+		ioc->usg_pages += (((u64)sba_sg_iova(sglist) & ~IOVP_MASK) + sba_sg_len(sglist) + IOVP_SIZE - 1) >> PAGE_SHIFT;
+#endif
+		++sglist;
+	}
+
+	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__,  nents);
+
+#ifdef ASSERT_PDIR_SANITY
+	spin_lock_irqsave(&ioc->res_lock, flags);
+	sba_check_pdir(ioc,"Check after sba_unmap_sg()");
+	spin_unlock_irqrestore(&ioc->res_lock, flags);
+#endif
+
+}
+
+unsigned long
+sba_dma_address (struct scatterlist *sg)
+{
+	return ((unsigned long)sba_sg_iova(sg));
+}
+
+int
+sba_dma_supported (struct pci_dev *dev, u64 mask)
+{
+	return 1;
+}
+
+/**************************************************************
+*
+*   Initialization and claim
+*
+***************************************************************/
+
+static void __init
+ioc_iova_init(struct ioc *ioc)
+{
+	u32 iova_space_mask;
+	int iov_order, tcnfg;
+	int agp_found = 0;
+	struct pci_dev *device;
+
+	/*
+	** Firmware programs the base and size of a "safe IOVA space"
+	** (one that doesn't overlap memory or LMMIO space) in the
+	** IBASE and IMASK registers.
+	*/
+	ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL;
+	ioc->iov_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1;
+
+	if (ioc->ibase == 0) {
+		if (((unsigned long) ioc->ioc_hpa & 0x3000UL) == 0x2000)
+			ioc->ibase = 0xc0000000;
+		else
+			ioc->ibase = 0x80000000;
+		printk("WARNING: IBASE is zero; setting to 0x%lx\n", ioc->ibase);
+	}
+
+	if (ioc->ibase < 0xfed00000UL && ioc->ibase + ioc->iov_size >= 0xfee00000UL) {
+		printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n");
+		ioc->iov_size /= 2;
+	}
+
+	/*
+	** iov_order is always based on a 1GB IOVA space since we want to
+	** turn on the other half for AGP GART.
+	*/
+	iov_order = get_order(ioc->iov_size >> (IOVP_SHIFT - PAGE_SHIFT));
+	ioc->pdir_size = (ioc->iov_size / IOVP_SIZE) * sizeof(u64);
+
+	DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits) PDIR size 0x%0x\n",
+		__FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20,
+		iov_order + PAGE_SHIFT, ioc->pdir_size);
+
+	/* FIXME : DMA HINTs not used */
+	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
+	ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
+
+	ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL,
+						   get_order(ioc->pdir_size));
+	if (!ioc->pdir_base)
+		panic(PFX "Couldn't allocate I/O Page Table\n");
+
+	memset(ioc->pdir_base, 0, ioc->pdir_size);
+
+	DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
+		__FUNCTION__, ioc->pdir_base, ioc->pdir_size,
+		ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+
+	ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
+	WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+	DBG_INIT(" base %p\n", ioc->pdir_base);
+
+	/* build IMASK for IOC and Elroy */
+	iova_space_mask =  0xffffffff;
+	iova_space_mask <<= (iov_order + PAGE_SHIFT);
+	ioc->imask = iova_space_mask;
+
+	DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n",
+		__FUNCTION__, ioc->ibase, ioc->imask);
+
+	/*
+	** FIXME: Hint registers are programmed with default hint
+	** values during boot, so hints should be sane even if we
+	** can't reprogram them the way drivers want.
+	*/
+	WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
+
+	/*
+	** Setting the upper bits makes checking for bypass addresses
+	** a little faster later on.
+	*/
+	ioc->imask |= 0xFFFFFFFF00000000UL;
+
+	/* Set I/O PDIR Page size to system page size */
+	switch (PAGE_SHIFT) {
+		case 12: tcnfg = 0; break;	/*  4K */
+		case 13: tcnfg = 1; break;	/*  8K */
+		case 14: tcnfg = 2; break;	/* 16K */
+		case 16: tcnfg = 3; break;	/* 64K */
+		default:
+			panic(PFX "Unsupported system page size %d",
+				1 << PAGE_SHIFT);
+			break;
+	}
+	WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG);
+
+	/*
+	** Program the IOC's ibase and enable IOVA translation
+	** Bit zero == enable bit.
+	*/
+	WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE);
+
+	/*
+	** Clear I/O TLB of any possible entries.
+	** (Yes. This is a bit paranoid...but so what)
+	*/
+	WRITE_REG(0 | 31, ioc->ioc_hpa + IOC_PCOM);
+
+	/*
+	** If an AGP device is present, only use half of the IOV space
+	** for PCI DMA.  Unfortunately we can't know ahead of time
+	** whether GART support will actually be used, for now we
+	** can just key on an AGP device found in the system.
+	** We program the next pdir index after we stop w/ a key for
+	** the GART code to handshake on.
+	*/
+	pci_for_each_dev(device)
+		agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
+
+	if (agp_found && reserve_sba_gart) {
+		DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n", __FUNCTION__);
+		ioc->pdir_size /= 2;
+		((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE;
+	}
+}
+
+static void __init
+ioc_resource_init(struct ioc *ioc)
+{
+	spin_lock_init(&ioc->res_lock);
+
+	/* resource map size dictated by pdir_size */
+	ioc->res_size = ioc->pdir_size / sizeof(u64); /* entries */
+	ioc->res_size >>= 3;  /* convert bit count to byte count */
+	DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size);
+
+	ioc->res_map = (char *) __get_free_pages(GFP_KERNEL,
+						 get_order(ioc->res_size));
+	if (!ioc->res_map)
+		panic(PFX "Couldn't allocate resource map\n");
+
+	memset(ioc->res_map, 0, ioc->res_size);
+	/* next available IOVP - circular search */
+	ioc->res_hint = (unsigned long *) ioc->res_map;
+
+#ifdef ASSERT_PDIR_SANITY
+	/* Mark first bit busy - ie no IOVA 0 */
+	ioc->res_map[0] = 0x1;
+	ioc->pdir_base[0] = 0x8000000000000000ULL | ZX1_SBA_IOMMU_COOKIE;
+#endif
+
+	DBG_INIT("%s() res_map %x %p\n", __FUNCTION__,
+		 ioc->res_size, (void *) ioc->res_map);
+}
+
+static void __init
+ioc_sac_init(struct ioc *ioc)
+{
+	struct pci_dev *sac = NULL;
+	struct pci_controller *controller = NULL;
+
+	/*
+	 * pci_alloc_consistent() must return a DMA address which is
+	 * SAC (single address cycle) addressable, so allocate a
+	 * pseudo-device to enforce that.
+	 */
+	sac = kmalloc(sizeof(*sac), GFP_KERNEL);
+	if (!sac)
+		panic(PFX "Couldn't allocate struct pci_dev");
+	memset(sac, 0, sizeof(*sac));
+
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		panic(PFX "Couldn't allocate struct pci_controller");
+	memset(controller, 0, sizeof(*controller));
+
+	controller->iommu = ioc;
+	sac->sysdata = controller;
+	sac->dma_mask = 0xFFFFFFFFUL;
+	ioc->sac_only_dev = sac;
+}
+
+static void __init
+ioc_zx1_init(struct ioc *ioc)
+{
+	if (ioc->rev < 0x20)
+		panic(PFX "IOC 2.0 or later required for IOMMU support\n");
+
+	ioc->dma_mask = 0xFFFFFFFFFFUL;
+}
+
+typedef void (initfunc)(struct ioc *);
+
+struct ioc_iommu {
+	u32 func_id;
+	char *name;
+	initfunc *init;
+};
+
+static struct ioc_iommu ioc_iommu_info[] __initdata = {
+	{ ZX1_IOC_ID, "zx1", ioc_zx1_init },
+	{ REO_IOC_ID, "REO" },
+};
+
+static struct ioc * __init
+ioc_init(u64 hpa, void *handle)
+{
+	struct ioc *ioc;
+	struct ioc_iommu *info;
+
+	ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
+	if (!ioc)
+		return NULL;
+
+	memset(ioc, 0, sizeof(*ioc));
+
+	ioc->next = ioc_list;
+	ioc_list = ioc;
+
+	ioc->handle = handle;
+	ioc->ioc_hpa = ioremap(hpa, 0x1000);
+
+	ioc->func_id = READ_REG(ioc->ioc_hpa + IOC_FUNC_ID);
+	ioc->rev = READ_REG(ioc->ioc_hpa + IOC_FCLASS) & 0xFFUL;
+	ioc->dma_mask = 0xFFFFFFFFFFFFFFFFUL;	/* conservative */
+
+	for (info = ioc_iommu_info; info < ioc_iommu_info + ARRAY_SIZE(ioc_iommu_info); info++) {
+		if (ioc->func_id == info->func_id) {
+			ioc->name = info->name;
+			if (info->init)
+				(info->init)(ioc);
+		}
+	}
+	if (!ioc->name)
+		ioc->name = "Unknown";
+
+	ioc_iova_init(ioc);
+	ioc_resource_init(ioc);
+	ioc_sac_init(ioc);
+
+	printk(KERN_INFO PFX
+		"Found %s IOC %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
+		ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
+		hpa, ioc->iov_size >> 20, ioc->ibase);
+
+	return ioc;
+}
+
+
+
+/**************************************************************************
+**
+**   SBA initialization code (HW and SW)
+**
+**   o identify SBA chip itself
+**   o FIXME: initialize DMA hints for reasonable defaults
+**
+**************************************************************************/
+
+#ifdef CONFIG_PROC_FS
+static int
+sba_proc_info_one(char *buf, struct ioc *ioc)
+{
+	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
+	unsigned long i = 0, avg = 0, min, max;
+
+	sprintf(buf, "Hewlett Packard %s IOC rev %d.%d\n",
+		ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF));
+	sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
+		buf,
+		(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
+		total_pages);
+
+	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
+		total_pages - ioc->used_pages, ioc->used_pages,
+		(int) (ioc->used_pages * 100 / total_pages));
+	
+	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
+		buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
+
+	min = max = ioc->avg_search[0];
+	for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
+		avg += ioc->avg_search[i];
+		if (ioc->avg_search[i] > max) max = ioc->avg_search[i];
+		if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
+	}
+	avg /= SBA_SEARCH_SAMPLE;
+	sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+		buf, min, avg, max);
+
+	sprintf(buf, "%spci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->msingle_calls, ioc->msingle_pages,
+		(int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls));
+#ifdef ALLOW_IOV_BYPASS
+	sprintf(buf, "%spci_map_single(): %12ld bypasses\n",
+	        buf, ioc->msingle_bypass);
+#endif
+
+	sprintf(buf, "%spci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->usingle_calls, ioc->usingle_pages,
+		(int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls));
+#ifdef ALLOW_IOV_BYPASS
+	sprintf(buf, "%spci_unmap_single: %12ld bypasses\n",
+	        buf, ioc->usingle_bypass);
+#endif
+
+	sprintf(buf, "%spci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->msg_calls, ioc->msg_pages,
+		(int) ((ioc->msg_pages * 1000)/ioc->msg_calls));
+#ifdef ALLOW_IOV_BYPASS
+	sprintf(buf, "%spci_map_sg()    : %12ld bypasses\n",
+	        buf, ioc->msg_bypass);
+#endif
+
+	sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
+		buf, ioc->usg_calls, ioc->usg_pages,
+		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
+
+	return strlen(buf);
+}
+
+static int
+sba_proc_info(char *buf, char **start, off_t offset, int len)
+{
+	struct ioc *ioc;
+	char *base = buf;
+
+	for (ioc = ioc_list; ioc; ioc = ioc->next) {
+		buf += sba_proc_info_one(buf, ioc);
+	}
+
+	return strlen(base);
+}
+
+static int
+sba_resource_map_one(char *buf, struct ioc *ioc)
+{
+	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
+	int i;
+
+	buf[0] = '\0';
+	for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) {
+		if ((i & 7) == 0)
+		    strcat(buf,"\n   ");
+		sprintf(buf, "%s %08x", buf, *res_ptr);
+	}
+	strcat(buf, "\n");
+
+	return strlen(buf);
+}
+
+static int
+sba_resource_map(char *buf, char **start, off_t offset, int len)
+{
+	struct ioc *ioc;
+	char *base = buf;
+
+	for (ioc = ioc_list; ioc; ioc = ioc->next) {
+		buf += sba_resource_map_one(buf, ioc);
+	}
+
+	return strlen(base);
+}
+#endif
+
+void
+sba_enable_device(struct pci_dev *dev)
+{
+	acpi_handle handle, parent;
+	acpi_status status;
+	struct ioc *ioc;
+
+	handle = PCI_CONTROLLER(dev)->acpi_handle;
+	if (!handle)
+		return;
+
+	/*
+	 * The IOC scope encloses PCI root bridges in the ACPI
+	 * namespace, so work our way out until we find an IOC we
+	 * claimed previously.
+	 */
+	do {
+		for (ioc = ioc_list; ioc; ioc = ioc->next)
+			if (ioc->handle == handle) {
+				PCI_CONTROLLER(dev)->iommu = ioc;
+				return;
+			}
+
+		status = acpi_get_parent(handle, &parent);
+		handle = parent;
+	} while (ACPI_SUCCESS(status));
+
+	printk("No IOC for %s in ACPI\n", dev->slot_name);
+}
+
+static int __init
+acpi_sba_ioc_add(struct acpi_device *device)
+{
+	struct ioc *ioc;
+	acpi_status status;
+	u64 hpa, length;
+
+	/*
+	 * Only SBA appears in ACPI namespace.  It encloses the PCI
+	 * root bridges, and its CSR space includes the IOC function.
+	 */
+	status = acpi_hp_csr_space(device->handle, &hpa, &length);
+	if (ACPI_FAILURE(status))
+		return 1;
+	ioc = ioc_init(hpa + ZX1_IOC_OFFSET, device->handle);
+	if (!ioc)
+		return 1;
+
+	return 0;
+}
+
+static int __init
+acpi_ioc_add(struct acpi_device *device)
+{
+	struct ioc *ioc;
+	acpi_status status;
+	u64 hpa, length;
+
+	status = acpi_hp_csr_space(device->handle, &hpa, &length);
+	if (ACPI_FAILURE(status))
+		return 1;
+	ioc = ioc_init(hpa, device->handle);
+	if (!ioc)
+		return 1;
+
+	return 0;
+}
+
+static struct acpi_driver acpi_sba_ioc_driver = {
+	name:		"IOC IOMMU Driver",
+	ids:		"HWP0001",
+	ops: {
+		add:	acpi_sba_ioc_add,
+     },
+};
+
+static struct acpi_driver acpi_ioc_driver = {
+	name:		"IOC IOMMU Driver",
+	ids:		"HWP0004",
+	ops: {
+		add:	acpi_ioc_add,
+     },
+};
+
+void __init
+ioc_acpi_init(void)
+{
+	acpi_bus_register_driver(&acpi_sba_ioc_driver);
+	acpi_bus_register_driver(&acpi_ioc_driver);
+}
+
+void __init
+sba_init(void)
+{
+	ioc_acpi_init();
+
+#ifdef CONFIG_PROC_FS
+	if (ioc_list) {
+		struct proc_dir_entry * proc_mckinley_root;
+
+		proc_mckinley_root = proc_mkdir("bus/mckinley",0);
+		create_proc_info_entry(ioc_list->name, 0, proc_mckinley_root, sba_proc_info);
+		create_proc_info_entry("bitmap", 0, proc_mckinley_root, sba_resource_map);
+	}
+#endif
+}
+
+static int __init
+nosbagart(char *str)
+{
+	reserve_sba_gart = 0;
+	return 1;
+}
+
+__setup("nosbagart", nosbagart);
+
+EXPORT_SYMBOL(sba_init);
+EXPORT_SYMBOL(sba_map_single);
+EXPORT_SYMBOL(sba_unmap_single);
+EXPORT_SYMBOL(sba_map_sg);
+EXPORT_SYMBOL(sba_unmap_sg);
+EXPORT_SYMBOL(sba_dma_address);
+EXPORT_SYMBOL(sba_dma_supported);
+EXPORT_SYMBOL(sba_alloc_consistent);
+EXPORT_SYMBOL(sba_free_consistent);
diff -urN linux-2.4.20-pre6/arch/ia64/hp/hpsim_console.c linux-2.4.20-pre7/arch/ia64/hp/hpsim_console.c
--- linux-2.4.20-pre6/arch/ia64/hp/hpsim_console.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/hp/hpsim_console.c	Wed Dec 31 16:00:00 1969
@@ -1,61 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/console.h>
-
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/pal.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-
-#include "hpsim_ssc.h"
-
-static int simcons_init (struct console *, char *);
-static void simcons_write (struct console *, const char *, unsigned);
-static kdev_t simcons_console_device (struct console *);
-
-struct console hpsim_cons = {
-	name:		"simcons",
-	write:		simcons_write,
-	device:		simcons_console_device,
-	setup:		simcons_init,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-
-static int
-simcons_init (struct console *cons, char *options)
-{
-	return 0;
-}
-
-static void
-simcons_write (struct console *cons, const char *buf, unsigned count)
-{
-	unsigned long ch;
-
-	while (count-- > 0) {
-		ch = *buf++;
-		ia64_ssc(ch, 0, 0, 0, SSC_PUTCHAR);
-		if (ch == '\n')
-		  ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
-	}
-}
-
-static kdev_t
-simcons_console_device (struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
-}
diff -urN linux-2.4.20-pre6/arch/ia64/hp/hpsim_irq.c linux-2.4.20-pre7/arch/ia64/hp/hpsim_irq.c
--- linux-2.4.20-pre6/arch/ia64/hp/hpsim_irq.c	Thu Apr  5 12:51:47 2001
+++ linux-2.4.20-pre7/arch/ia64/hp/hpsim_irq.c	Wed Dec 31 16:00:00 1969
@@ -1,46 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/irq.h>
-
-static unsigned int
-hpsim_irq_startup (unsigned int irq)
-{
-	return 0;
-}
-
-static void
-hpsim_irq_noop (unsigned int irq)
-{
-}
-
-static struct hw_interrupt_type irq_type_hp_sim = {
-	typename:	"hpsim",
-	startup:	hpsim_irq_startup,
-	shutdown:	hpsim_irq_noop,
-	enable:		hpsim_irq_noop,
-	disable:	hpsim_irq_noop,
-	ack:		hpsim_irq_noop,
-	end:		hpsim_irq_noop,
-	set_affinity:	(void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
-};
-
-void __init
-hpsim_irq_init (void)
-{
-	irq_desc_t *idesc;
-	int i;
-
-	for (i = 0; i < NR_IRQS; ++i) {
-		idesc = irq_desc(i);
-		if (idesc->handler == &no_irq_type)
-			idesc->handler = &irq_type_hp_sim;
-	}
-}
diff -urN linux-2.4.20-pre6/arch/ia64/hp/hpsim_machvec.c linux-2.4.20-pre7/arch/ia64/hp/hpsim_machvec.c
--- linux-2.4.20-pre6/arch/ia64/hp/hpsim_machvec.c	Fri Aug 11 19:09:06 2000
+++ linux-2.4.20-pre7/arch/ia64/hp/hpsim_machvec.c	Wed Dec 31 16:00:00 1969
@@ -1,2 +0,0 @@
-#define MACHVEC_PLATFORM_NAME	hpsim
-#include <asm/machvec_init.h>
diff -urN linux-2.4.20-pre6/arch/ia64/hp/hpsim_setup.c linux-2.4.20-pre7/arch/ia64/hp/hpsim_setup.c
--- linux-2.4.20-pre6/arch/ia64/hp/hpsim_setup.c	Tue Jul 31 10:30:08 2001
+++ linux-2.4.20-pre7/arch/ia64/hp/hpsim_setup.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/console.h>
-
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/pal.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-
-#include "hpsim_ssc.h"
-
-extern struct console hpsim_cons;
-
-/*
- * Simulator system call.
- */
-asm (".text\n"
-     ".align 32\n"
-     ".global ia64_ssc\n"
-     ".proc ia64_ssc\n"
-     "ia64_ssc:\n"
-     "mov r15=r36\n"
-     "break 0x80001\n"
-     "br.ret.sptk.many rp\n"
-     ".endp\n");
-
-void
-ia64_ssc_connect_irq (long intr, long irq)
-{
-	ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
-}
-
-void
-ia64_ctl_trace (long on)
-{
-	ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
-}
-
-void __init
-hpsim_setup (char **cmdline_p)
-{
-	ROOT_DEV = to_kdev_t(0x0801);		/* default to first SCSI drive */
-
-	register_console (&hpsim_cons);
-}
diff -urN linux-2.4.20-pre6/arch/ia64/hp/hpsim_ssc.h linux-2.4.20-pre7/arch/ia64/hp/hpsim_ssc.h
--- linux-2.4.20-pre6/arch/ia64/hp/hpsim_ssc.h	Sun Feb  6 18:42:40 2000
+++ linux-2.4.20-pre7/arch/ia64/hp/hpsim_ssc.h	Wed Dec 31 16:00:00 1969
@@ -1,36 +0,0 @@
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#ifndef _IA64_PLATFORM_HPSIM_SSC_H
-#define _IA64_PLATFORM_HPSIM_SSC_H
-
-/* Simulator system calls: */
-
-#define SSC_CONSOLE_INIT		20
-#define SSC_GETCHAR			21
-#define SSC_PUTCHAR			31
-#define SSC_CONNECT_INTERRUPT		58
-#define SSC_GENERATE_INTERRUPT		59
-#define SSC_SET_PERIODIC_INTERRUPT	60
-#define SSC_GET_RTC			65
-#define SSC_EXIT			66
-#define SSC_LOAD_SYMBOLS		69
-#define SSC_GET_TOD			74
-#define SSC_CTL_TRACE			76
-
-#define SSC_NETDEV_PROBE		100
-#define SSC_NETDEV_SEND			101
-#define SSC_NETDEV_RECV			102
-#define SSC_NETDEV_ATTACH		103
-#define SSC_NETDEV_DETACH		104
-
-/*
- * Simulator system call.
- */
-extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
-
-#endif /* _IA64_PLATFORM_HPSIM_SSC_H */
diff -urN linux-2.4.20-pre6/arch/ia64/hp/sim/Makefile linux-2.4.20-pre7/arch/ia64/hp/sim/Makefile
--- linux-2.4.20-pre6/arch/ia64/hp/sim/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/sim/Makefile	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,13 @@
+#
+# ia64/platform/hp/sim/Makefile
+#
+# Copyright (C) 1999 Silicon Graphics, Inc.
+# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
+#
+
+O_TARGET := sim.o
+
+obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
+obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_console.c linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_console.c
--- linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_console.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_console.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,62 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pal.h>
+#include <asm/machvec.h>
+#include <asm/pgtable.h>
+#include <asm/sal.h>
+
+#include "hpsim_ssc.h"
+
+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,
+	setup:		simcons_init,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+static int
+simcons_init (struct console *cons, char *options)
+{
+	return 0;
+}
+
+static void
+simcons_write (struct console *cons, const char *buf, unsigned count)
+{
+	unsigned long ch;
+
+	while (count-- > 0) {
+		ch = *buf++;
+		ia64_ssc(ch, 0, 0, 0, SSC_PUTCHAR);
+		if (ch == '\n')
+		  ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
+	}
+}
+
+static kdev_t
+simcons_console_device (struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
diff -urN linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_irq.c linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_irq.c
--- linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_irq.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,46 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/irq.h>
+
+static unsigned int
+hpsim_irq_startup (unsigned int irq)
+{
+	return 0;
+}
+
+static void
+hpsim_irq_noop (unsigned int irq)
+{
+}
+
+static struct hw_interrupt_type irq_type_hp_sim = {
+	typename:	"hpsim",
+	startup:	hpsim_irq_startup,
+	shutdown:	hpsim_irq_noop,
+	enable:		hpsim_irq_noop,
+	disable:	hpsim_irq_noop,
+	ack:		hpsim_irq_noop,
+	end:		hpsim_irq_noop,
+	set_affinity:	(void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
+};
+
+void __init
+hpsim_irq_init (void)
+{
+	irq_desc_t *idesc;
+	int i;
+
+	for (i = 0; i < NR_IRQS; ++i) {
+		idesc = irq_desc(i);
+		if (idesc->handler == &no_irq_type)
+			idesc->handler = &irq_type_hp_sim;
+	}
+}
diff -urN linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_machvec.c linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_machvec.c
--- linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_machvec.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_machvec.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,2 @@
+#define MACHVEC_PLATFORM_NAME	hpsim
+#include <asm/machvec_init.h>
diff -urN linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_setup.c linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_setup.c
--- linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_setup.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,58 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pal.h>
+#include <asm/machvec.h>
+#include <asm/pgtable.h>
+#include <asm/sal.h>
+
+#include "hpsim_ssc.h"
+
+extern struct console hpsim_cons;
+
+/*
+ * Simulator system call.
+ */
+asm (".text\n"
+     ".align 32\n"
+     ".global ia64_ssc\n"
+     ".proc ia64_ssc\n"
+     "ia64_ssc:\n"
+     "mov r15=r36\n"
+     "break 0x80001\n"
+     "br.ret.sptk.many rp\n"
+     ".endp\n");
+
+void
+ia64_ssc_connect_irq (long intr, long irq)
+{
+	ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
+}
+
+void
+ia64_ctl_trace (long on)
+{
+	ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
+}
+
+void __init
+hpsim_setup (char **cmdline_p)
+{
+	ROOT_DEV = to_kdev_t(0x0801);		/* default to first SCSI drive */
+
+	register_console (&hpsim_cons);
+}
diff -urN linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_ssc.h linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_ssc.h
--- linux-2.4.20-pre6/arch/ia64/hp/sim/hpsim_ssc.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/sim/hpsim_ssc.h	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,36 @@
+/*
+ * Platform dependent support for HP simulator.
+ *
+ * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
+ */
+#ifndef _IA64_PLATFORM_HPSIM_SSC_H
+#define _IA64_PLATFORM_HPSIM_SSC_H
+
+/* Simulator system calls: */
+
+#define SSC_CONSOLE_INIT		20
+#define SSC_GETCHAR			21
+#define SSC_PUTCHAR			31
+#define SSC_CONNECT_INTERRUPT		58
+#define SSC_GENERATE_INTERRUPT		59
+#define SSC_SET_PERIODIC_INTERRUPT	60
+#define SSC_GET_RTC			65
+#define SSC_EXIT			66
+#define SSC_LOAD_SYMBOLS		69
+#define SSC_GET_TOD			74
+#define SSC_CTL_TRACE			76
+
+#define SSC_NETDEV_PROBE		100
+#define SSC_NETDEV_SEND			101
+#define SSC_NETDEV_RECV			102
+#define SSC_NETDEV_ATTACH		103
+#define SSC_NETDEV_DETACH		104
+
+/*
+ * Simulator system call.
+ */
+extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
+
+#endif /* _IA64_PLATFORM_HPSIM_SSC_H */
diff -urN linux-2.4.20-pre6/arch/ia64/hp/zx1/Makefile linux-2.4.20-pre7/arch/ia64/hp/zx1/Makefile
--- linux-2.4.20-pre6/arch/ia64/hp/zx1/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/zx1/Makefile	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,13 @@
+#
+# ia64/platform/hp/zx1/Makefile
+#
+# Copyright (C) 2002 Hewlett Packard
+# Copyright (C) Alex Williamson (alex_williamson@hp.com)
+#
+
+O_TARGET := zx1.o
+
+obj-y := hpzx1_misc.o
+obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.20-pre7/arch/ia64/hp/zx1/hpzx1_machvec.c
--- linux-2.4.20-pre6/arch/ia64/hp/zx1/hpzx1_machvec.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/zx1/hpzx1_machvec.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,2 @@
+#define MACHVEC_PLATFORM_NAME	hpzx1
+#include <asm/machvec_init.h>
diff -urN linux-2.4.20-pre6/arch/ia64/hp/zx1/hpzx1_misc.c linux-2.4.20-pre7/arch/ia64/hp/zx1/hpzx1_misc.c
--- linux-2.4.20-pre6/arch/ia64/hp/zx1/hpzx1_misc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/hp/zx1/hpzx1_misc.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,308 @@
+/*
+ * Misc. support for HP zx1 chipset support
+ *
+ * Copyright (C) 2002 Hewlett-Packard Co
+ * Copyright (C) 2002 Alex Williamson <alex_williamson@hp.com>
+ * Copyright (C) 2002 Bjorn Helgaas <bjorn_helgaas@hp.com>
+ */
+
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
+
+#include <asm/dma.h>
+#include <asm/iosapic.h>
+
+extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *, unsigned long *);
+
+#define PFX "hpzx1: "
+
+static int hpzx1_devices;
+
+struct fake_pci_dev {
+	unsigned long csr_base;
+	unsigned long csr_size;
+	unsigned long mapped_csrs;	// ioremapped
+	int sizing;			// in middle of BAR sizing operation?
+};
+
+#define PCI_FAKE_DEV(dev)	((struct fake_pci_dev *) \
+					PCI_CONTROLLER(dev)->platform_data)
+
+static struct pci_ops *orig_pci_ops;
+
+#define HP_CFG_RD(sz, bits, name) \
+static int hp_cfg_read##sz (struct pci_dev *dev, int where, u##bits *value) \
+{ \
+	struct fake_pci_dev *fake_dev; \
+	if (!(fake_dev = PCI_FAKE_DEV(dev))) \
+		return orig_pci_ops->name(dev, where, value); \
+	\
+	if (where == PCI_BASE_ADDRESS_0) { \
+		if (fake_dev->sizing) \
+			*value = ~(fake_dev->csr_size - 1); \
+		else \
+			*value = (fake_dev->csr_base & \
+				    PCI_BASE_ADDRESS_MEM_MASK) | \
+				PCI_BASE_ADDRESS_SPACE_MEMORY; \
+		fake_dev->sizing = 0; \
+		return PCIBIOS_SUCCESSFUL; \
+	} \
+	*value = read##sz(fake_dev->mapped_csrs + where); \
+	if (where == PCI_COMMAND) \
+		*value |= PCI_COMMAND_MEMORY; /* SBA omits this */ \
+	return PCIBIOS_SUCCESSFUL; \
+}
+
+#define HP_CFG_WR(sz, bits, name) \
+static int hp_cfg_write##sz (struct pci_dev *dev, int where, u##bits value) \
+{ \
+	struct fake_pci_dev *fake_dev; \
+	\
+	if (!(fake_dev = PCI_FAKE_DEV(dev))) \
+		return orig_pci_ops->name(dev, where, value); \
+	\
+	if (where == PCI_BASE_ADDRESS_0) { \
+		if (value == (u##bits) ~0) \
+			fake_dev->sizing = 1; \
+		return PCIBIOS_SUCCESSFUL; \
+	} else \
+		write##sz(value, fake_dev->mapped_csrs + where); \
+	return PCIBIOS_SUCCESSFUL; \
+}
+
+HP_CFG_RD(b,  8, read_byte)
+HP_CFG_RD(w, 16, read_word)
+HP_CFG_RD(l, 32, read_dword)
+HP_CFG_WR(b,  8, write_byte)
+HP_CFG_WR(w, 16, write_word)
+HP_CFG_WR(l, 32, write_dword)
+
+static struct pci_ops hp_pci_conf = {
+	hp_cfg_readb,
+	hp_cfg_readw,
+	hp_cfg_readl,
+	hp_cfg_writeb,
+	hp_cfg_writew,
+	hp_cfg_writel,
+};
+
+static void
+hpzx1_fake_pci_dev(char *name, unsigned int busnum, unsigned long addr, unsigned int size)
+{
+	struct pci_controller *controller;
+	struct fake_pci_dev *fake;
+	int slot;
+	struct pci_dev *dev;
+	struct pci_bus *b, *bus = NULL;
+	u8 hdr;
+
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name,
+			(void *) addr);
+		return;
+	}
+	memset(controller, 0, sizeof(*controller));
+
+        fake = kmalloc(sizeof(*fake), GFP_KERNEL);
+	if (!fake) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p) sysdata\n", name,
+			(void *) addr);
+		kfree(controller);
+		return;
+	}
+
+	memset(fake, 0, sizeof(*fake));
+	fake->csr_base = addr;
+	fake->csr_size = size;
+	fake->mapped_csrs = (unsigned long) ioremap(addr, size);
+	fake->sizing = 0;
+	controller->platform_data = fake;
+
+	pci_for_each_bus(b)
+		if (busnum == b->number) {
+			bus = b;
+			break;
+		}
+
+	if (!bus) {
+		printk(KERN_ERR PFX "No host bus 0x%02x for %s (0x%p)\n",
+			busnum, name, (void *) addr);
+		kfree(fake);
+		kfree(controller);
+		return;
+	}
+
+	for (slot = 0x1e; slot; slot--)
+		if (!pci_find_slot(busnum, PCI_DEVFN(slot, 0)))
+			break;
+
+	if (slot < 0) {
+		printk(KERN_ERR PFX "No space for %s (0x%p) on bus 0x%02x\n",
+			name, (void *) addr, busnum);
+		kfree(fake);
+		kfree(controller);
+		return;
+	}
+
+        dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		printk(KERN_ERR PFX "No memory for %s (0x%p)\n", name,
+			(void *) addr);
+		kfree(fake);
+		kfree(controller);
+		return;
+	}
+
+	bus->ops = &hp_pci_conf;	// replace pci ops for this bus
+
+	memset(dev, 0, sizeof(*dev));
+	dev->bus = bus;
+	dev->sysdata = controller;
+	dev->devfn = PCI_DEVFN(slot, 0);
+	pci_read_config_word(dev, PCI_VENDOR_ID, &dev->vendor);
+	pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
+	pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr);
+	dev->hdr_type = hdr & 0x7f;
+
+	pci_setup_device(dev);
+
+	// pci_insert_device() without running /sbin/hotplug
+	list_add_tail(&dev->bus_list, &bus->devices);
+	list_add_tail(&dev->global_list, &pci_devices);
+
+	printk(KERN_INFO PFX "%s at 0x%lx; pci dev %s\n", name, addr,
+		dev->slot_name);
+
+	hpzx1_devices++;
+}
+
+static acpi_status
+hpzx1_sba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
+{
+	u64 csr_base = 0, csr_length = 0;
+	acpi_status status;
+	char *name = context;
+	char fullname[16];
+
+	status = acpi_hp_csr_space(obj, &csr_base, &csr_length);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	/*
+	 * Only SBA shows up in ACPI namespace, so its CSR space
+	 * includes both SBA and IOC.  Make SBA and IOC show up
+	 * separately in PCI space.
+	 */
+	sprintf(fullname, "%s SBA", name);
+	hpzx1_fake_pci_dev(fullname, 0, csr_base, 0x1000);
+	sprintf(fullname, "%s IOC", name);
+	hpzx1_fake_pci_dev(fullname, 0, csr_base + 0x1000, 0x1000);
+
+	return AE_OK;
+}
+
+static acpi_status
+hpzx1_lba_probe(acpi_handle obj, u32 depth, void *context, void **ret)
+{
+	u64 csr_base = 0, csr_length = 0;
+	acpi_status status;
+	NATIVE_UINT busnum;
+	char *name = context;
+	char fullname[32];
+
+	status = acpi_hp_csr_space(obj, &csr_base, &csr_length);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	status = acpi_evaluate_integer(obj, METHOD_NAME__BBN, NULL, &busnum);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_WARNING PFX "evaluate _BBN fail=0x%x\n", status);
+		busnum = 0;	// no _BBN; stick it on bus 0
+	}
+
+	sprintf(fullname, "%s _BBN 0x%02x", name, (unsigned int) busnum);
+	hpzx1_fake_pci_dev(fullname, busnum, csr_base, csr_length);
+
+	return AE_OK;
+}
+
+static void
+hpzx1_acpi_dev_init(void)
+{
+	extern struct pci_ops *pci_root_ops;
+
+	orig_pci_ops = pci_root_ops;
+
+	/*
+	 * Make fake PCI devices for the following hardware in the
+	 * ACPI namespace.  This makes it more convenient for drivers
+	 * because they can claim these devices based on PCI
+	 * information, rather than needing to know about ACPI.  The
+	 * 64-bit "HPA" space for this hardware is available as BAR
+	 * 0/1.
+	 *
+	 * HWP0001: Single IOC SBA w/o IOC in namespace
+	 * HWP0002: LBA device
+	 * HWP0003: AGP LBA device
+	 */
+	acpi_get_devices("HWP0001", hpzx1_sba_probe, "HWP0001", NULL);
+#ifdef CONFIG_IA64_HP_PROTO
+	if (hpzx1_devices) {
+#endif
+	acpi_get_devices("HWP0002", hpzx1_lba_probe, "HWP0002 PCI LBA", NULL);
+	acpi_get_devices("HWP0003", hpzx1_lba_probe, "HWP0003 AGP LBA", NULL);
+
+#ifdef CONFIG_IA64_HP_PROTO
+	}
+
+#define ZX1_FUNC_ID_VALUE    (PCI_DEVICE_ID_HP_ZX1_SBA << 16) | PCI_VENDOR_ID_HP
+	/*
+	 * Early protos don't have bridges in the ACPI namespace, so
+	 * if we didn't find anything, add the things we know are
+	 * there.
+	 */
+	if (hpzx1_devices == 0) {
+		u64 hpa, csr_base;
+
+		csr_base = 0xfed00000UL;
+		hpa = (u64) ioremap(csr_base, 0x2000);
+		if (__raw_readl(hpa) == ZX1_FUNC_ID_VALUE) {
+			hpzx1_fake_pci_dev("HWP0001 SBA", 0, csr_base, 0x1000);
+			hpzx1_fake_pci_dev("HWP0001 IOC", 0, csr_base + 0x1000,
+					    0x1000);
+
+			csr_base = 0xfed24000UL;
+			iounmap(hpa);
+			hpa = (u64) ioremap(csr_base, 0x1000);
+			hpzx1_fake_pci_dev("HWP0003 AGP LBA", 0x40, csr_base,
+					    0x1000);
+		}
+		iounmap(hpa);
+	}
+#endif
+}
+
+extern void sba_init(void);
+
+void
+hpzx1_pci_fixup (int phase)
+{
+	iosapic_pci_fixup(phase);
+	switch (phase) {
+	      case 0:
+		/* zx1 has a hardware I/O TLB which lets us DMA from any device to any address */
+		MAX_DMA_ADDRESS = ~0UL;
+		break;
+
+	      case 1:
+		hpzx1_acpi_dev_init();
+		sba_init();
+		break;
+	}
+}
diff -urN linux-2.4.20-pre6/arch/ia64/ia32/binfmt_elf32.c linux-2.4.20-pre7/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.20-pre6/arch/ia64/ia32/binfmt_elf32.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/ia32/binfmt_elf32.c	Thu Sep 12 20:01:39 2002
@@ -47,6 +47,8 @@
 #define ELF_PLAT_INIT(_r)		ia64_elf32_init(_r)
 #define setup_arg_pages(bprm)		ia32_setup_arg_pages(bprm)
 #define elf_map				elf32_map
+
+#undef SET_PERSONALITY
 #define SET_PERSONALITY(ex, ibcs2)	elf32_set_personality()
 
 /* Ugly but avoids duplication */
diff -urN linux-2.4.20-pre6/arch/ia64/ia32/ia32_traps.c linux-2.4.20-pre7/arch/ia64/ia32/ia32_traps.c
--- linux-2.4.20-pre6/arch/ia64/ia32/ia32_traps.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/ia32/ia32_traps.c	Thu Sep 12 20:01:39 2002
@@ -20,7 +20,7 @@
 {
 	switch ((isr >> 16) & 0xff) {
 	      case 0:	/* Instruction intercept fault */
-	      case 3:	/* Locked Data reference fault */
+	      case 4:	/* Locked Data reference fault */
 	      case 1:	/* Gate intercept trap */
 		return -1;
 
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/Makefile linux-2.4.20-pre7/arch/ia64/kernel/Makefile
--- linux-2.4.20-pre6/arch/ia64/kernel/Makefile	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/Makefile	Thu Sep 12 20:01:39 2002
@@ -17,6 +17,7 @@
 	 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_HP_ZX1) += iosapic.o
 obj-$(CONFIG_IA64_DIG) += iosapic.o
 obj-$(CONFIG_IA64_PALINFO) += palinfo.o
 obj-$(CONFIG_EFI_VARS) += efivars.o
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/acpi.c linux-2.4.20-pre7/arch/ia64/kernel/acpi.c
--- linux-2.4.20-pre6/arch/ia64/kernel/acpi.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/acpi.c	Thu Sep 12 20:01:39 2002
@@ -1,21 +1,34 @@
 /*
- * Advanced Configuration and Power Interface
+ *  acpi.c - Architecture-Specific Low-Level ACPI Support
  *
- * Based on 'ACPI Specification 1.0b' February 2, 1999 and
- * 'IA-64 Extensions to ACPI Specification' Revision 0.6
+ *  Copyright (C) 1999 VA Linux Systems
+ *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
+ *  Copyright (C) 2000, 2002 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *  Copyright (C) 2000 Intel Corp.
+ *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
+ *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000 Hewlett-Packard Co.
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2000 Intel Corp.
- * Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
- *      ACPI based kernel configuration manager.
- *      ACPI 2.0 & IA64 ext 0.71
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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/kernel.h>
 #include <linux/sched.h>
@@ -23,657 +36,801 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/irq.h>
-#ifdef CONFIG_SERIAL_ACPI
-#include <linux/acpi_serial.h>
-#endif
-
-#include <asm/acpi-ext.h>
-#include <asm/acpikcfg.h>
-#include <asm/efi.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
 #include <asm/machvec.h>
 #include <asm/page.h>
+#include <asm/system.h>
 
-#undef ACPI_DEBUG		/* Guess what this does? */
 
-/* global array to record platform interrupt vectors for generic int routing */
-int platform_irq_list[ACPI_MAX_PLATFORM_IRQS];
+#define PREFIX			"ACPI: "
 
-/* These are ugly but will be reclaimed by the kernel */
-int __initdata available_cpus;
-int __initdata total_cpus;
+asm (".weak iosapic_register_intr");
+asm (".weak iosapic_override_isa_irq");
+asm (".weak iosapic_register_platform_intr");
+asm (".weak iosapic_init");
+asm (".weak iosapic_version");
 
 void (*pm_idle) (void);
 void (*pm_power_off) (void);
 
-asm (".weak iosapic_register_irq");
-asm (".weak iosapic_register_legacy_irq");
-asm (".weak iosapic_register_platform_irq");
-asm (".weak iosapic_init");
-asm (".weak iosapic_version");
+unsigned char acpi_kbd_controller_present = 1;
 
 const char *
 acpi_get_sysname (void)
 {
-	/* the following should go away once we have an ACPI parser: */
 #ifdef CONFIG_IA64_GENERIC
-	return "hpsim";
+	unsigned long rsdp_phys;
+	struct acpi20_table_rsdp *rsdp;
+	struct acpi_table_xsdt *xsdt;
+	struct acpi_table_header *hdr;
+
+	rsdp_phys = acpi_find_rsdp();
+	if (!rsdp_phys) {
+		printk("ACPI 2.0 RSDP not found, default to \"dig\"\n");
+		return "dig";
+	}
+
+	rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
+	if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
+		printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
+		return "dig";
+	}
+
+	xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
+	hdr = &xsdt->header;
+	if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
+		printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
+		return "dig";
+	}
+
+	if (!strcmp(hdr->oem_id, "HP")) {
+		return "hpzx1";
+	}
+
+	return "dig";
 #else
 # if defined (CONFIG_IA64_HP_SIM)
 	return "hpsim";
+# elif defined (CONFIG_IA64_HP_ZX1)
+	return "hpzx1";
 # elif defined (CONFIG_IA64_SGI_SN1)
 	return "sn1";
 # elif defined (CONFIG_IA64_SGI_SN2)
 	return "sn2";
 # elif defined (CONFIG_IA64_DIG)
 	return "dig";
+# elif defined (CONFIG_IA64_HP_ZX1)
+	return "hpzx1";
 # else
 #	error Unknown platform.  Fix acpi.c.
 # endif
 #endif
+}
+
+#ifdef CONFIG_ACPI
+
+/**
+ * acpi_get_crs - Return the current resource settings for a device
+ * obj: A handle for this device
+ * buf: A buffer to be populated by this call.
+ *
+ * Pass a valid handle, typically obtained by walking the namespace and a
+ * pointer to an allocated buffer, and this function will fill in the buffer
+ * with a list of acpi_resource structures.
+ */
+acpi_status
+acpi_get_crs (acpi_handle obj, acpi_buffer *buf)
+{
+	acpi_status result;
+	buf->length = 0;
+	buf->pointer = NULL;
+
+	result = acpi_get_current_resources(obj, buf);
+	if (result != AE_BUFFER_OVERFLOW)
+		return result;
+	buf->pointer = kmalloc(buf->length, GFP_KERNEL);
+	if (!buf->pointer)
+		return -ENOMEM;
+
+	return acpi_get_current_resources(obj, buf);
+}
+
+acpi_resource *
+acpi_get_crs_next (acpi_buffer *buf, int *offset)
+{
+	acpi_resource *res;
+
+	if (*offset >= buf->length)
+		return NULL;
+
+	res = buf->pointer + *offset;
+	*offset += res->length;
+	return res;
+}
+
+acpi_resource_data *
+acpi_get_crs_type (acpi_buffer *buf, int *offset, int type)
+{
+	for (;;) {
+		acpi_resource *res = acpi_get_crs_next(buf, offset);
+		if (!res)
+			return NULL;
+		if (res->id == type)
+			return &res->data;
+	}
+}
+
+void
+acpi_dispose_crs (acpi_buffer *buf)
+{
+	kfree(buf->pointer);
+}
+
+static void
+acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra)
+{
+	int offset = 0;
+	acpi_resource_address16 *addr16;
+	acpi_resource_address32 *addr32;
+	acpi_resource_address64 *addr64;
+
+	for (;;) {
+		acpi_resource *res = acpi_get_crs_next(buf, &offset);
+		if (!res)
+			return;
+		switch (res->id) {
+			case ACPI_RSTYPE_ADDRESS16:
+				addr16 = (acpi_resource_address16 *) &res->data;
+
+				if (type == addr16->resource_type) {
+					*base = addr16->min_address_range;
+					*length = addr16->address_length;
+					*tra = addr16->address_translation_offset;
+					return;
+				}
+				break;
+			case ACPI_RSTYPE_ADDRESS32:
+				addr32 = (acpi_resource_address32 *) &res->data;
+				if (type == addr32->resource_type) {
+					*base = addr32->min_address_range;
+					*length = addr32->address_length;
+					*tra = addr32->address_translation_offset;
+					return;
+				}
+				break;
+			case ACPI_RSTYPE_ADDRESS64:
+				addr64 = (acpi_resource_address64 *) &res->data;
+				if (type == addr64->resource_type) {
+					*base = addr64->min_address_range;
+					*length = addr64->address_length;
+					*tra = addr64->address_translation_offset;
+					return;
+				}
+				break;
+		}
+	}
+}
+
+acpi_status
+acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra)
+{
+	acpi_status status;
+	acpi_buffer buf;
+
+	*base = 0;
+	*length = 0;
+	*tra = 0;
+
+	status = acpi_get_crs(obj, &buf);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
+		return status;
+	}
+
+	acpi_get_crs_addr(&buf, type, base, length, tra);
+
+	acpi_dispose_crs(&buf);
+
+	return AE_OK;
+}
+
+typedef struct {
+	u8	guid_id;
+	u8	guid[16];
+	u8	csr_base[8];
+	u8	csr_length[8];
+} acpi_hp_vendor_long;
+
+#define HP_CCSR_LENGTH 0x21
+#define HP_CCSR_TYPE 0x2
+#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \
+			      0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
+
+acpi_status
+acpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
+{
+	int i, offset = 0;
+	acpi_status status;
+	acpi_buffer buf;
+	acpi_resource_vendor *res;
+	acpi_hp_vendor_long *hp_res;
+	efi_guid_t vendor_guid;
+
+	*csr_base = 0;
+	*csr_length = 0;
 
+	status = acpi_get_crs(obj, &buf);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
+		return status;
+	}
+
+	res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);
+	if (!res) {
+		printk(KERN_ERR PREFIX "Failed to find config space for device\n");
+		acpi_dispose_crs(&buf);
+		return AE_NOT_FOUND;
+	}
+
+	hp_res = (acpi_hp_vendor_long *)(res->reserved);
+
+	if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) {
+		printk(KERN_ERR PREFIX "Unknown Vendor data\n");
+		acpi_dispose_crs(&buf);
+		return AE_TYPE; /* Revisit error? */
+	}
+
+	memcpy(&vendor_guid, hp_res->guid, sizeof(efi_guid_t));
+	if (efi_guidcmp(vendor_guid, HP_CCSR_GUID) != 0) {
+		printk(KERN_ERR PREFIX "Vendor GUID does not match\n");
+		acpi_dispose_crs(&buf);
+		return AE_TYPE; /* Revisit error? */
+	}
+
+	for (i = 0 ; i < 8 ; i++) {
+		*csr_base |= ((u64)(hp_res->csr_base[i]) << (i * 8));
+		*csr_length |= ((u64)(hp_res->csr_length[i]) << (i * 8));
+	}
+
+	acpi_dispose_crs(&buf);
+
+	return AE_OK;
 }
+#endif /* CONFIG_ACPI */
+
+#ifdef CONFIG_ACPI_BOOT
+
+#define ACPI_MAX_PLATFORM_INTERRUPTS	256
+
+/* Array to record platform interrupt vectors for generic interrupt routing. */
+int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 };
+
+enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
 
 /*
- * Interrupt routing API for device drivers.
- * Provides the interrupt vector for a generic platform event
- * (currently only CPEI implemented)
+ * Interrupt routing API for device drivers.  Provides interrupt vector for
+ * a generic platform event.  Currently only CPEI is implemented.
  */
 int
-acpi_request_vector(u32 int_type)
+acpi_request_vector (u32 int_type)
 {
 	int vector = -1;
 
-	if (int_type < ACPI_MAX_PLATFORM_IRQS) {
+	if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
 		/* correctable platform error interrupt */
-		vector = platform_irq_list[int_type];
+		vector = platform_intr_list[int_type];
 	} else
 		printk("acpi_request_vector(): invalid interrupt type\n");
 
 	return vector;
 }
 
-/*
- * Configure legacy IRQ information.
- */
-static void __init
-acpi_legacy_irq (char *p)
+char *
+__acpi_map_table (unsigned long phys_addr, unsigned long size)
 {
-	acpi_entry_int_override_t *legacy = (acpi_entry_int_override_t *) p;
-	unsigned long polarity = 0, edge_triggered = 0;
+	return __va(phys_addr);
+}
 
-	/*
-	 * If the platform we're running doesn't define
-	 * iosapic_register_legacy_irq(), we ignore this info...
-	 */
-	if (!iosapic_register_legacy_irq)
-		return;
+/* --------------------------------------------------------------------------
+                            Boot-time Table Parsing
+   -------------------------------------------------------------------------- */
 
-	switch (legacy->flags) {
-	      case 0x5:	polarity = 1; edge_triggered = 1; break;
-	      case 0x7: polarity = 0; edge_triggered = 1; break;
-	      case 0xd: polarity = 1; edge_triggered = 0; break;
-	      case 0xf: polarity = 0; edge_triggered = 0; break;
-	      default:
-		printk("    ACPI Legacy IRQ 0x%02x: Unknown flags 0x%x\n", legacy->isa_irq,
-		       legacy->flags);
-		break;
-	}
-	iosapic_register_legacy_irq(legacy->isa_irq, legacy->pin, polarity, edge_triggered);
-}
+static int			total_cpus __initdata;
+static int			available_cpus __initdata;
+struct acpi_table_madt *	acpi_madt __initdata;
+static u8			has_8259;
 
-/*
- * ACPI 2.0 tables parsing functions
- */
 
-static unsigned long
-readl_unaligned(void *p)
+static int __init
+acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
 {
-	unsigned long ret;
+	struct acpi_table_lapic_addr_ovr *lapic;
+
+	lapic = (struct acpi_table_lapic_addr_ovr *) header;
+	if (!lapic)
+		return -EINVAL;
 
-	memcpy(&ret, p, sizeof(long));
-	return ret;
+	acpi_table_print_madt_entry(header);
+
+	if (lapic->address) {
+		iounmap((void *) ipi_base_addr);
+		ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
+	}
+
+	return 0;
 }
 
-/*
- * Identify usable CPU's and remember them for SMP bringup later.
- */
-static void __init
-acpi20_lsapic (char *p)
+
+static int __init
+acpi_parse_lsapic (acpi_table_entry_header *header)
 {
-	int add = 1;
+	struct acpi_table_lsapic *lsapic;
 
-	acpi20_entry_lsapic_t *lsapic = (acpi20_entry_lsapic_t *) p;
-	printk("      CPU %.04x:%.04x: ", lsapic->eid, lsapic->id);
+	lsapic = (struct acpi_table_lsapic *) header;
+	if (!lsapic)
+		return -EINVAL;
 
-	if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
-		printk("disabled.\n");
-		add = 0;
-	}
+	acpi_table_print_madt_entry(header);
 
-#ifdef CONFIG_SMP
-	smp_boot_data.cpu_phys_id[total_cpus] = -1;
-#endif
-	if (add) {
+	printk("CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
+
+	if (lsapic->flags.enabled) {
 		available_cpus++;
-		printk("available");
+		printk(" enabled");
 #ifdef CONFIG_SMP
 		smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
 		if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])
 			printk(" (BSP)");
 #endif
-		printk(".\n");
 	}
+	else {
+		printk(" disabled");
+#ifdef CONFIG_SMP
+		smp_boot_data.cpu_phys_id[total_cpus] = -1;
+#endif
+	}
+
+	printk("\n");
+
 	total_cpus++;
+	return 0;
 }
 
-/*
- * Extract iosapic info from madt (again) to determine which iosapic
- * this platform interrupt resides in
- */
+
+static int __init
+acpi_parse_lapic_nmi (acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_nmi *lacpi_nmi;
+
+	lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
+	if (!lacpi_nmi)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	/* TBD: Support lapic_nmi entries */
+
+	return 0;
+}
+
+
 static int __init
-acpi20_which_iosapic (int global_vector, acpi_madt_t *madt, u32 *irq_base, char **iosapic_address)
+acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address)
 {
-	acpi_entry_iosapic_t *iosapic;
-	char *p, *end;
-	int ver, max_pin;
+	struct acpi_table_iosapic *iosapic;
+	int ver;
+	int max_pin;
+	char *p;
+	char *end;
+
+	if (!gsi_base || !iosapic_address)
+		return -ENODEV;
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
+	p = (char *) (acpi_madt + 1);
+	end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt));
 
 	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_IO_SAPIC:
-			/* collect IOSAPIC info for platform int use later */
-			iosapic = (acpi_entry_iosapic_t *)p;
-			*irq_base = iosapic->irq_base;
+		if (*p == ACPI_MADT_IOSAPIC) {
+			iosapic = (struct acpi_table_iosapic *) p;
+
+			*gsi_base = iosapic->global_irq_base;
 			*iosapic_address = ioremap(iosapic->address, 0);
-			/* is this the iosapic we're looking for? */
+
 			ver = iosapic_version(*iosapic_address);
 			max_pin = (ver >> 16) & 0xff;
-			if ((global_vector - *irq_base) <= max_pin)
-				return 0;		/* found it! */
-			break;
-		      default:
-			break;
+
+			if ((gsi - *gsi_base) <= max_pin)
+				return 0;	/* Found it! */
 		}
 		p += p[1];
 	}
-	return 1;
+	return -ENODEV;
 }
 
-/*
- * Info on platform interrupt sources: NMI, PMI, INIT, etc.
- */
-static void __init
-acpi20_platform (char *p, acpi_madt_t *madt)
+
+static int __init
+acpi_parse_iosapic (acpi_table_entry_header *header)
 {
+	struct acpi_table_iosapic *iosapic;
+
+	iosapic = (struct acpi_table_iosapic *) header;
+	if (!iosapic)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (iosapic_init) {
+#ifndef CONFIG_ITANIUM
+		/* PCAT_COMPAT flag indicates dual-8259 setup */
+		iosapic_init(iosapic->address, iosapic->global_irq_base,
+			     acpi_madt->flags.pcat_compat);
+#else
+		/* Firmware on old Itanium systems is broken */
+		iosapic_init(iosapic->address, iosapic->global_irq_base, 1);
+#endif
+	}
+	return 0;
+}
+
+
+static int __init
+acpi_parse_plat_int_src (acpi_table_entry_header *header)
+{
+	struct acpi_table_plat_int_src *plintsrc;
 	int vector;
-	u32 irq_base;
+	u32 gsi_base;
 	char *iosapic_address;
-	unsigned long polarity = 0, trigger = 0;
-	acpi20_entry_platform_src_t *plat = (acpi20_entry_platform_src_t *) p;
 
-	printk("PLATFORM: IOSAPIC %x -> Vector %x on CPU %.04u:%.04u\n",
-	       plat->iosapic_vector, plat->global_vector, plat->eid, plat->id);
+	plintsrc = (struct acpi_table_plat_int_src *) header;
+	if (!plintsrc)
+		return -EINVAL;
 
-	/* record platform interrupt vectors for generic int routing code */
+	acpi_table_print_madt_entry(header);
 
-	if (!iosapic_register_platform_irq) {
-		printk("acpi20_platform(): no ACPI platform IRQ support\n");
-		return;
-	}
-
-	/* extract polarity and trigger info from flags */
-	switch (plat->flags) {
-	      case 0x5: polarity = 1; trigger = 1; break;
-	      case 0x7: polarity = 0; trigger = 1; break;
-	      case 0xd: polarity = 1; trigger = 0; break;
-	      case 0xf: polarity = 0; trigger = 0; break;
-	      default:
-		printk("acpi20_platform(): unknown flags 0x%x\n", plat->flags);
-		break;
-	}
-
-	/* which iosapic does this IRQ belong to? */
-	if (acpi20_which_iosapic(plat->global_vector, madt, &irq_base, &iosapic_address)) {
-		printk("acpi20_platform(): I/O SAPIC not found!\n");
-		return;
+	if (!iosapic_register_platform_intr) {
+		printk(KERN_WARNING PREFIX "No ACPI platform interrupt support\n");
+		return -ENODEV;
+	}
+
+	if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) {
+		printk(KERN_WARNING PREFIX "IOSAPIC not found\n");
+		return -ENODEV;
 	}
 
 	/*
-	 * get vector assignment for this IRQ, set attributes, and program the IOSAPIC
-	 * routing table
+	 * Get vector assignment for this interrupt, set attributes,
+	 * and program the IOSAPIC routing table.
 	 */
-	vector = iosapic_register_platform_irq(plat->int_type,
-					       plat->global_vector,
-					       plat->iosapic_vector,
-					       plat->eid,
-					       plat->id,
-					       polarity,
-					       trigger,
-					       irq_base,
-					       iosapic_address);
-	platform_irq_list[plat->int_type] = vector;
+	vector = iosapic_register_platform_intr(plintsrc->type,
+						plintsrc->global_irq,
+						plintsrc->iosapic_vector,
+						plintsrc->eid,
+						plintsrc->id,
+						(plintsrc->flags.polarity == 1) ? 1 : 0,
+						(plintsrc->flags.trigger == 1) ? 1 : 0,
+						gsi_base,
+						iosapic_address);
+
+	platform_intr_list[plintsrc->type] = vector;
+	return 0;
 }
 
-/*
- * Override the physical address of the local APIC in the MADT stable header.
- */
-static void __init
-acpi20_lapic_addr_override (char *p)
+
+static int __init
+acpi_parse_int_src_ovr (acpi_table_entry_header *header)
 {
-	acpi20_entry_lapic_addr_override_t * lapic = (acpi20_entry_lapic_addr_override_t *) p;
+	struct acpi_table_int_src_ovr *p;
 
-	if (lapic->lapic_address) {
-		iounmap((void *)ipi_base_addr);
-		ipi_base_addr = (unsigned long) ioremap(lapic->lapic_address, 0);
+	p = (struct acpi_table_int_src_ovr *) header;
+	if (!p)
+		return -EINVAL;
 
-		printk("LOCAL ACPI override to 0x%lx(p=0x%lx)\n",
-		       ipi_base_addr, lapic->lapic_address);
-	}
+	acpi_table_print_madt_entry(header);
+
+	/* Ignore if the platform doesn't support overrides */
+	if (!iosapic_override_isa_irq)
+		return 0;
+
+	iosapic_override_isa_irq(p->bus_irq, p->global_irq,
+				 (p->flags.polarity == 1) ? 1 : 0,
+				 (p->flags.trigger == 1) ? 1 : 0);
+
+	return 0;
 }
 
-/*
- * Parse the ACPI Multiple APIC Description Table
- */
-static void __init
-acpi20_parse_madt (acpi_madt_t *madt)
+
+static int __init
+acpi_parse_nmi_src (acpi_table_entry_header *header)
 {
-	acpi_entry_iosapic_t *iosapic = NULL;
-	acpi20_entry_lsapic_t *lsapic = NULL;
-	char *p, *end;
-	int i;
-
-	/* Base address of IPI Message Block */
-	if (madt->lapic_address) {
-		ipi_base_addr = (unsigned long) ioremap(madt->lapic_address, 0);
-		printk("Lapic address set to 0x%lx\n", ipi_base_addr);
-	} else
-		printk("Lapic address set to default 0x%lx\n", ipi_base_addr);
+	struct acpi_table_nmi_src *nmi_src;
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
+	nmi_src = (struct acpi_table_nmi_src*) header;
+	if (!nmi_src)
+		return -EINVAL;
 
-	/* Initialize platform interrupt vector array */
-	for (i = 0; i < ACPI_MAX_PLATFORM_IRQS; i++)
-		platform_irq_list[i] = -1;
+	acpi_table_print_madt_entry(header);
 
-	/*
-	 * Split-up entry parsing to ensure ordering.
-	 */
-	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_LOCAL_APIC_ADDR_OVERRIDE:
-			printk("ACPI 2.0 MADT: LOCAL APIC Override\n");
-			acpi20_lapic_addr_override(p);
-			break;
-
-		      case ACPI20_ENTRY_LOCAL_SAPIC:
-			printk("ACPI 2.0 MADT: LOCAL SAPIC\n");
-			lsapic = (acpi20_entry_lsapic_t *) p;
-			acpi20_lsapic(p);
-			break;
-
-		      case ACPI20_ENTRY_IO_SAPIC:
-			iosapic = (acpi_entry_iosapic_t *) p;
-			if (iosapic_init)
-				/*
-				 * The PCAT_COMPAT flag indicates that the system has a
-				 * dual-8259 compatible setup.
-				 */
-				iosapic_init(iosapic->address, iosapic->irq_base,
-#ifdef CONFIG_ITANIUM
-					     1 /* fw on some Itanium systems is broken... */
-#else
-					     (madt->flags & MADT_PCAT_COMPAT)
-#endif
-					);
-			break;
+	/* TBD: Support nimsrc entries */
 
-		      case ACPI20_ENTRY_PLATFORM_INT_SOURCE:
-			printk("ACPI 2.0 MADT: PLATFORM INT SOURCE\n");
-			acpi20_platform(p, madt);
-			break;
-
-		      case ACPI20_ENTRY_LOCAL_APIC:
-			printk("ACPI 2.0 MADT: LOCAL APIC entry\n"); break;
-		      case ACPI20_ENTRY_IO_APIC:
-			printk("ACPI 2.0 MADT: IO APIC entry\n"); break;
-		      case ACPI20_ENTRY_NMI_SOURCE:
-			printk("ACPI 2.0 MADT: NMI SOURCE entry\n"); break;
-		      case ACPI20_ENTRY_LOCAL_APIC_NMI:
-			printk("ACPI 2.0 MADT: LOCAL APIC NMI entry\n"); break;
-		      case ACPI20_ENTRY_INT_SRC_OVERRIDE:
-			break;
-		      default:
-			printk("ACPI 2.0 MADT: unknown entry skip\n"); break;
-			break;
-		}
-		p += p[1];
-	}
+	return 0;
+}
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
 
-	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_LOCAL_APIC:
-			if (lsapic) break;
-			printk("ACPI 2.0 MADT: LOCAL APIC entry\n");
-			/* parse local apic if there's no local Sapic */
-			break;
-		      case ACPI20_ENTRY_IO_APIC:
-			if (iosapic) break;
-			printk("ACPI 2.0 MADT: IO APIC entry\n");
-			/* parse ioapic if there's no ioSapic */
-			break;
-		      default:
-			break;
-		}
-		p += p[1];
-	}
+static int __init
+acpi_parse_madt (unsigned long phys_addr, unsigned long size)
+{
+	if (!phys_addr || !size)
+		return -EINVAL;
 
-	p = (char *) (madt + 1);
-	end = p + (madt->header.length - sizeof(acpi_madt_t));
+	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
 
-	while (p < end) {
-		switch (*p) {
-		      case ACPI20_ENTRY_INT_SRC_OVERRIDE:
-			printk("ACPI 2.0 MADT: INT SOURCE Override\n");
-			acpi_legacy_irq(p);
-			break;
-		      default:
-			break;
-		}
-		p += p[1];
-	}
+	/* remember the value for reference after free_initmem() */
+	has_8259 = acpi_madt->flags.pcat_compat;
+
+	/* Get base address of IPI Message Block */
 
-	/* Make bootup pretty */
-	printk("      %d CPUs available, %d CPUs total\n",
-		available_cpus, total_cpus);
+	if (acpi_madt->lapic_address)
+		ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
+
+	printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
+	return 0;
 }
 
-int __init
-acpi20_parse (acpi20_rsdp_t *rsdp20)
+
+static int __init
+acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
 {
-# ifdef CONFIG_ACPI
-	acpi_xsdt_t *xsdt;
-	acpi_desc_table_hdr_t *hdrp;
-	acpi_madt_t *madt = NULL;
-	int tables, i;
+	struct acpi_table_header *fadt_header;
+	fadt_descriptor_rev2 *fadt;
+	u32 sci_irq, gsi_base;
+	char *iosapic_address;
 
-	if (strncmp(rsdp20->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) {
-		printk("ACPI 2.0 RSDP signature incorrect!\n");
-		return 0;
-	} else {
-		printk("ACPI 2.0 Root System Description Ptr at 0x%lx\n",
-			(unsigned long)rsdp20);
-	}
+	if (!phys_addr || !size)
+		return -EINVAL;
 
-	xsdt = __va(rsdp20->xsdt);
-	hdrp = &xsdt->header;
-	if (strncmp(hdrp->signature,
-		ACPI_XSDT_SIG, ACPI_XSDT_SIG_LEN)) {
-		printk("ACPI 2.0 XSDT signature incorrect. Trying RSDT\n");
-		/* RSDT parsing here */
-		return 0;
-	} else {
-		printk("ACPI 2.0 XSDT at 0x%lx (p=0x%lx)\n",
-		(unsigned long)xsdt, (unsigned long)rsdp20->xsdt);
-	}
+	fadt_header = (struct acpi_table_header *) __va(phys_addr);
 
-	printk("ACPI 2.0: %.6s %.8s %d.%d\n",
-		hdrp->oem_id,
-		hdrp->oem_table_id,
-		hdrp->oem_revision >> 16,
-		hdrp->oem_revision & 0xffff);
+	if (fadt_header->revision != 3)
+		return -ENODEV;		/* Only deal with ACPI 2.0 FADT */
 
-	acpi_cf_init((void *)rsdp20);
+	fadt = (fadt_descriptor_rev2 *) fadt_header;
 
-	tables =(hdrp->length -sizeof(acpi_desc_table_hdr_t))>>3;
+	if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
+		acpi_kbd_controller_present = 0;
 
-	for (i = 0; i < tables; i++) {
-		hdrp = (acpi_desc_table_hdr_t *) __va(readl_unaligned(&xsdt->entry_ptrs[i]));
-		printk("        :table %4.4s found\n", hdrp->signature);
+	sci_irq = fadt->sci_int;
 
-		/* Only interested int the MADT table for now ... */
-		if (strncmp(hdrp->signature,
-			ACPI_MADT_SIG, ACPI_MADT_SIG_LEN) != 0)
-			continue;
+	if (has_8259 && sci_irq < 16)
+		return 0;	/* legacy, no setup required */
+
+	if (!iosapic_register_intr)
+		return -ENODEV;
+
+	if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address))
+		iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address);
+
+	return 0;
+}
 
-		/* Save MADT pointer for later */
-		madt = (acpi_madt_t *) hdrp;
-		acpi20_parse_madt(madt);
-	}
 
 #ifdef CONFIG_SERIAL_ACPI
+
+#include <linux/acpi_serial.h>
+
+static int __init
+acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
+{
+	acpi_ser_t *spcr;
+	u32 gsi, gsi_base;
+	char *iosapic_address;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	if (!iosapic_register_intr)
+		return -ENODEV;
+
 	/*
-	 * Now we're interested in other tables.  We want the iosapics already
-	 * initialized, so we do it in a separate loop.
+	 * ACPI is able to describe serial ports that live at non-standard
+	 * memory addresses and use non-standard interrupts, either via
+	 * direct SAPIC mappings or via PCI interrupts.  We handle interrupt
+	 * routing for SAPIC-based (non-PCI) devices here.  Interrupt routing
+	 * for PCI devices will be handled when processing the PCI Interrupt
+	 * Routing Table (PRT).
 	 */
-	for (i = 0; i < tables; i++) {
-		hdrp = (acpi_desc_table_hdr_t *) __va(readl_unaligned(&xsdt->entry_ptrs[i]));
-		/*
-		 * search for SPCR and DBGP table entries so we can enable
-		 * non-pci interrupts to IO-SAPICs.
-		 */
-		if (!strncmp(hdrp->signature, ACPI_SPCRT_SIG, ACPI_SPCRT_SIG_LEN) ||
-		    !strncmp(hdrp->signature, ACPI_DBGPT_SIG, ACPI_DBGPT_SIG_LEN))
-		{
-			acpi_ser_t *spcr = (void *)hdrp;
-			unsigned long global_int;
-
-			setup_serial_acpi(hdrp);
-
-			/*
-			 * ACPI is able to describe serial ports that live at non-standard
-			 * memory space addresses and use SAPIC interrupts.  If not also
-			 * PCI devices, there would be no interrupt vector information for
-			 * them.  This checks for and fixes that situation.
-			 */
-			if (spcr->length < sizeof(acpi_ser_t))
-				/* table is not long enough for full info, thus no int */
-				break;
 
-			/*
-			 * If the device is not in PCI space, but uses a SAPIC interrupt,
-			 * we need to program the SAPIC so that serial can autoprobe for
-			 * the IA64 interrupt vector later on.  If the device is in PCI
-			 * space, it should already be setup via the PCI vectors
-			 */
-			if (spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE &&
-			    spcr->int_type == ACPI_SERIAL_INT_SAPIC)
-			{
-				u32 irq_base;
-				char *iosapic_address;
-				int vector;
-
-				/* We have a UART in memory space with a SAPIC interrupt */
-				global_int = (  (spcr->global_int[3] << 24)
-					      | (spcr->global_int[2] << 16)
-					      | (spcr->global_int[1] << 8)
-					      | spcr->global_int[0]);
-
-				if (!iosapic_register_irq)
-					continue;
-
-				/* which iosapic does this IRQ belong to? */
-				if (acpi20_which_iosapic(global_int, madt, &irq_base,
-							 &iosapic_address) == 0)
-				{
-					vector = iosapic_register_irq(global_int,
-					                              1, /* active high polarity */
-					                              1, /* edge triggered */
-					                              irq_base,
-					                              iosapic_address);
-				}
-			}
-		}
-	}
-#endif
-	acpi_cf_terminate();
+	spcr = (acpi_ser_t *) __va(phys_addr);
+	setup_serial_acpi(spcr);
 
-#  ifdef CONFIG_SMP
-	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
-		available_cpus = 1; /* We've got at least one of these, no? */
+	if (spcr->length < sizeof(acpi_ser_t))
+		/* Table not long enough for full info, thus no interrupt */
+		return -ENODEV;
+
+	if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) &&
+	    (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) {
+
+		/* We have a UART in memory space with an SAPIC interrupt */
+
+		gsi = (spcr->global_int[3] << 24) |
+		      (spcr->global_int[2] << 16) |
+		      (spcr->global_int[1] << 8)  |
+		      (spcr->global_int[0]);
+
+		if (!acpi_find_iosapic(gsi, &gsi_base, &iosapic_address))
+			iosapic_register_intr(gsi, 1, 1,
+					      gsi_base, iosapic_address);
 	}
-	smp_boot_data.cpu_count = total_cpus;
-#  endif
-# endif /* CONFIG_ACPI */
-	return 1;
+	return 0;
 }
-/*
- * ACPI 1.0b with 0.71 IA64 extensions functions; should be removed once all
- * platforms start supporting ACPI 2.0
- */
 
-/*
- * Identify usable CPU's and remember them for SMP bringup later.
- */
-static void __init
-acpi_lsapic (char *p)
+#endif /*CONFIG_SERIAL_ACPI*/
+
+
+unsigned long __init
+acpi_find_rsdp (void)
 {
-	int add = 1;
+	unsigned long rsdp_phys = 0;
 
-	acpi_entry_lsapic_t *lsapic = (acpi_entry_lsapic_t *) p;
+	if (efi.acpi20)
+		rsdp_phys = __pa(efi.acpi20);
+	else if (efi.acpi)
+		printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
 
-	if ((lsapic->flags & LSAPIC_PRESENT) == 0)
-		return;
+	return rsdp_phys;
+}
 
-	printk("      CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id);
 
-	if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
-		printk("Disabled.\n");
-		add = 0;
-	} else if (lsapic->flags & LSAPIC_PERFORMANCE_RESTRICTED) {
-		printk("Performance Restricted; ignoring.\n");
-		add = 0;
-	}
+int __init
+acpi_boot_init (char *cmdline)
+{
+	int result;
 
-#ifdef CONFIG_SMP
-	smp_boot_data.cpu_phys_id[total_cpus] = -1;
-#endif
-	if (add) {
-		printk("Available.\n");
-		available_cpus++;
-#ifdef CONFIG_SMP
-		smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
-#endif /* CONFIG_SMP */
+	/* Initialize the ACPI boot-time table parser */
+	result = acpi_table_init(cmdline);
+	if (result)
+		return result;
+
+	/*
+	 * MADT
+	 * ----
+	 * Parse the Multiple APIC Description Table (MADT), if exists.
+	 * Note that this table provides platform SMP configuration
+	 * information -- the successor to MPS tables.
+	 */
+
+	if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
+		printk(KERN_ERR PREFIX "Can't find MADT\n");
+		goto skip_madt;
 	}
-	total_cpus++;
-}
 
-/*
- * Info on platform interrupt sources: NMI. PMI, INIT, etc.
- */
-static void __init
-acpi_platform (char *p)
-{
-	acpi_entry_platform_src_t *plat = (acpi_entry_platform_src_t *) p;
+	/* Local APIC */
 
-	printk("PLATFORM: IOSAPIC %x -> Vector %x on CPU %.04u:%.04u\n",
-	       plat->iosapic_vector, plat->global_vector, plat->eid, plat->id);
-}
+	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
+				  acpi_parse_lapic_addr_ovr) < 0)
+		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
 
-/*
- * Parse the ACPI Multiple SAPIC Table
- */
-static void __init
-acpi_parse_msapic (acpi_sapic_t *msapic)
-{
-	acpi_entry_iosapic_t *iosapic;
-	char *p, *end;
+	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC,
+				  acpi_parse_lsapic) < 1)
+		printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
 
-	/* Base address of IPI Message Block */
-	ipi_base_addr = (unsigned long) ioremap(msapic->interrupt_block, 0);
+	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI,
+				  acpi_parse_lapic_nmi) < 0)
+		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 
-	p = (char *) (msapic + 1);
-	end = p + (msapic->header.length - sizeof(acpi_sapic_t));
+	/* I/O APIC */
 
-	while (p < end) {
-		switch (*p) {
-		      case ACPI_ENTRY_LOCAL_SAPIC:
-			acpi_lsapic(p);
-			break;
-
-		      case ACPI_ENTRY_IO_SAPIC:
-			iosapic = (acpi_entry_iosapic_t *) p;
-			if (iosapic_init)
-				/*
-				 * The ACPI I/O SAPIC table doesn't have a PCAT_COMPAT
-				 * flag like the MADT table, but we can safely assume that
-				 * ACPI 1.0b systems have a dual-8259 setup.
-				 */
-				iosapic_init(iosapic->address, iosapic->irq_base, 1);
-			break;
-
-		      case ACPI_ENTRY_INT_SRC_OVERRIDE:
-			acpi_legacy_irq(p);
-			break;
-
-		      case ACPI_ENTRY_PLATFORM_INT_SOURCE:
-			acpi_platform(p);
-			break;
+	if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC,
+				  acpi_parse_iosapic) < 1)
+		printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entries\n");
 
-		      default:
-			break;
-		}
+	/* System-Level Interrupt Routing */
 
-		/* Move to next table entry. */
-		p += p[1];
-	}
+	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
+				  acpi_parse_plat_int_src) < 0)
+		printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
+
+	if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR,
+				  acpi_parse_int_src_ovr) < 0)
+		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
 
-	/* Make bootup pretty */
-	printk("      %d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+	if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC,
+				  acpi_parse_nmi_src) < 0)
+		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
+skip_madt:
+
+	/*
+	 * The FADT table contains an SCI_INT line, by which the system
+	 * gets interrupts such as power and sleep buttons.  If it's not
+	 * on a Legacy interrupt, it needs to be setup.
+	 */
+	if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)
+		printk(KERN_ERR PREFIX "Can't find FADT\n");
+
+#ifdef CONFIG_SERIAL_ACPI
+	acpi_table_parse(ACPI_SPCR, acpi_parse_spcr);
+#endif
+
+#ifdef CONFIG_SMP
+	if (available_cpus == 0) {
+		printk("ACPI: Found 0 CPUS; assuming 1\n");
+		available_cpus = 1; /* We've got at least one of these, no? */
+	}
+	smp_boot_data.cpu_count = total_cpus;
+#endif
+	/* Make boot-up look pretty */
+	printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+	return 0;
 }
 
+
+/* --------------------------------------------------------------------------
+                             PCI Interrupt Routing
+   -------------------------------------------------------------------------- */
+
 int __init
-acpi_parse (acpi_rsdp_t *rsdp)
+acpi_get_prt (struct pci_vector_struct **vectors, int *count)
 {
-# ifdef CONFIG_ACPI
-	acpi_rsdt_t *rsdt;
-	acpi_desc_table_hdr_t *hdrp;
-	long tables, i;
+	struct pci_vector_struct *vector;
+	struct list_head *node;
+	struct acpi_prt_entry *entry;
+	int i = 0;
 
-	if (strncmp(rsdp->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) {
-		printk("Uh-oh, ACPI RSDP signature incorrect!\n");
-		return 0;
-	}
+	if (!vectors || !count)
+		return -EINVAL;
 
-	rsdt = __va(rsdp->rsdt);
-	if (strncmp(rsdt->header.signature, ACPI_RSDT_SIG, ACPI_RSDT_SIG_LEN)) {
-		printk("Uh-oh, ACPI RDST signature incorrect!\n");
-		return 0;
+	*vectors = NULL;
+	*count = 0;
+
+	if (acpi_prt.count < 0) {
+		printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n");
+		return -ENODEV;
 	}
 
-	printk("ACPI: %.6s %.8s %d.%d\n", rsdt->header.oem_id, rsdt->header.oem_table_id,
-	       rsdt->header.oem_revision >> 16, rsdt->header.oem_revision & 0xffff);
+	/* Allocate vectors */
 
-	acpi_cf_init(rsdp);
+	*vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL);
+	if (!(*vectors))
+		return -ENOMEM;
 
-	tables = (rsdt->header.length - sizeof(acpi_desc_table_hdr_t)) / 8;
-	for (i = 0; i < tables; i++) {
-		hdrp = (acpi_desc_table_hdr_t *) __va(rsdt->entry_ptrs[i]);
+	/* Convert PRT entries to IOSAPIC PCI vectors */
 
-		/* Only interested int the MSAPIC table for now ... */
-		if (strncmp(hdrp->signature, ACPI_SAPIC_SIG, ACPI_SAPIC_SIG_LEN) != 0)
-			continue;
+	vector = *vectors;
 
-		acpi_parse_msapic((acpi_sapic_t *) hdrp);
+	list_for_each(node, &acpi_prt.entries) {
+		entry = (struct acpi_prt_entry *)node;
+		vector[i].segment = entry->id.segment;
+		vector[i].bus    = entry->id.bus;
+		vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;
+		vector[i].pin    = entry->pin;
+		vector[i].irq    = entry->link.index;
+		i++;
 	}
+	*count = acpi_prt.count;
+	return 0;
+}
 
-	acpi_cf_terminate();
+/* Assume IA64 always use I/O SAPIC */
 
-#  ifdef CONFIG_SMP
-	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
-		available_cpus = 1; /* We've got at least one of these, no? */
-	}
-	smp_boot_data.cpu_count = total_cpus;
-#  endif
-# endif /* CONFIG_ACPI */
-	return 1;
+int __init
+acpi_get_interrupt_model (int *type)
+{
+        if (!type)
+                return -EINVAL;
+
+	*type = ACPI_IRQ_MODEL_IOSAPIC;
+        return 0;
+}
+
+int
+acpi_irq_to_vector (u32 irq)
+{
+	if (has_8259 && irq < 16)
+		return isa_irq_to_vector(irq);
+
+	return gsi_to_vector(irq);
 }
+
+#endif /* CONFIG_ACPI_BOOT */
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/efi.c linux-2.4.20-pre7/arch/ia64/kernel/efi.c
--- linux-2.4.20-pre6/arch/ia64/kernel/efi.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/efi.c	Thu Sep 12 20:01:39 2002
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2001 Hewlett-Packard Co.
+ * Copyright (C) 1999-2002 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -24,8 +24,8 @@
 #include <linux/types.h>
 #include <linux/time.h>
 #include <linux/proc_fs.h>
+#include <linux/efi.h>
 
-#include <asm/efi.h>
 #include <asm/io.h>
 #include <asm/kregs.h>
 #include <asm/pgtable.h>
@@ -125,9 +125,79 @@
 	tv->tv_usec = tm.nanosecond / 1000;
 }
 
+static int
+is_available_memory (efi_memory_desc_t *md)
+{
+	if (!(md->attribute & EFI_MEMORY_WB))
+		return 0;
+
+	switch (md->type) {
+	      case EFI_LOADER_CODE:
+	      case EFI_LOADER_DATA:
+	      case EFI_BOOT_SERVICES_CODE:
+	      case EFI_BOOT_SERVICES_DATA:
+	      case EFI_CONVENTIONAL_MEMORY:
+		return 1;
+	}
+	return 0;
+}
+
 /*
- * Walks the EFI memory map and calls CALLBACK once for each EFI
- * memory descriptor that has memory that is available for OS use.
+ * Trim descriptor MD so its starts at address START_ADDR.  If the descriptor covers
+ * memory that is normally available to the kernel, issue a warning that some memory
+ * is being ignored.
+ */
+static void
+trim_bottom (efi_memory_desc_t *md, u64 start_addr)
+{
+	u64 num_skipped_pages;
+
+	if (md->phys_addr >= start_addr || !md->num_pages)
+		return;
+
+	num_skipped_pages = (start_addr - md->phys_addr) >> EFI_PAGE_SHIFT;
+	if (num_skipped_pages > md->num_pages)
+		num_skipped_pages = md->num_pages;
+
+	if (is_available_memory(md))
+		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
+		       "at 0x%lx\n", __FUNCTION__,
+		       (num_skipped_pages << EFI_PAGE_SHIFT) >> 10,
+		       md->phys_addr, start_addr - IA64_GRANULE_SIZE);
+	/*
+	 * NOTE: Don't set md->phys_addr to START_ADDR because that could cause the memory
+	 * descriptor list to become unsorted.  In such a case, md->num_pages will be
+	 * zero, so the Right Thing will happen.
+	 */
+	md->phys_addr += num_skipped_pages << EFI_PAGE_SHIFT;
+	md->num_pages -= num_skipped_pages;
+}
+
+static void
+trim_top (efi_memory_desc_t *md, u64 end_addr)
+{
+	u64 num_dropped_pages, md_end_addr;
+
+	md_end_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+	if (md_end_addr <= end_addr || !md->num_pages)
+		return;
+
+	num_dropped_pages = (md_end_addr - end_addr) >> EFI_PAGE_SHIFT;
+	if (num_dropped_pages > md->num_pages)
+		num_dropped_pages = md->num_pages;
+
+	if (is_available_memory(md))
+		printk(KERN_NOTICE "efi.%s: ignoring %luKB of memory at 0x%lx due to granule hole "
+		       "at 0x%lx\n", __FUNCTION__,
+		       (num_dropped_pages << EFI_PAGE_SHIFT) >> 10,
+		       md->phys_addr, end_addr);
+	md->num_pages -= num_dropped_pages;
+}
+
+/*
+ * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that
+ * has memory that is available for OS use.
  */
 void
 efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
@@ -137,9 +207,9 @@
 		u64 start;
 		u64 end;
 	} prev, curr;
-	void *efi_map_start, *efi_map_end, *p;
-	efi_memory_desc_t *md;
-	u64 efi_desc_size, start, end;
+	void *efi_map_start, *efi_map_end, *p, *q;
+	efi_memory_desc_t *md, *check_md;
+	u64 efi_desc_size, start, end, granule_addr, first_non_wb_addr = 0;
 
 	efi_map_start = __va(ia64_boot_param->efi_memmap);
 	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
@@ -147,27 +217,59 @@
 
 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
 		md = p;
-		switch (md->type) {
-		      case EFI_LOADER_CODE:
-		      case EFI_LOADER_DATA:
-		      case EFI_BOOT_SERVICES_CODE:
-		      case EFI_BOOT_SERVICES_DATA:
-		      case EFI_CONVENTIONAL_MEMORY:
-			if (!(md->attribute & EFI_MEMORY_WB))
-				continue;
-			if (md->phys_addr + (md->num_pages << 12) > mem_limit) {
+
+		/* skip over non-WB memory descriptors; that's all we're interested in... */
+		if (!(md->attribute & EFI_MEMORY_WB))
+			continue;
+
+		if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > first_non_wb_addr) {
+			/*
+			 * Search for the next run of contiguous WB memory.  Start search
+			 * at first granule boundary covered by md.
+			 */
+			granule_addr = ((md->phys_addr + IA64_GRANULE_SIZE - 1)
+					& -IA64_GRANULE_SIZE);
+			first_non_wb_addr = granule_addr;
+			for (q = p; q < efi_map_end; q += efi_desc_size) {
+				check_md = q;
+
+				if (check_md->attribute & EFI_MEMORY_WB)
+					trim_bottom(md, granule_addr);
+
+				if (check_md->phys_addr < granule_addr)
+					continue;
+
+				if (!(check_md->attribute & EFI_MEMORY_WB))
+					break;	/* hit a non-WB region; stop search */
+
+				if (check_md->phys_addr != first_non_wb_addr)
+					break;	/* hit a memory hole; stop search */
+
+				first_non_wb_addr += check_md->num_pages << EFI_PAGE_SHIFT;
+			}
+			/* round it down to the previous granule-boundary: */
+			first_non_wb_addr &= -IA64_GRANULE_SIZE;
+
+			if (!(first_non_wb_addr > granule_addr))
+				continue;	/* couldn't find enough contiguous memory */
+		}
+
+		/* BUG_ON((md->phys_addr >> IA64_GRANULE_SHIFT) < first_non_wb_addr); */
+
+		trim_top(md, first_non_wb_addr);
+
+		if (is_available_memory(md)) {
+			if (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) > mem_limit) {
 				if (md->phys_addr > mem_limit)
 					continue;
-				md->num_pages = (mem_limit - md->phys_addr) >> 12;
+				md->num_pages = (mem_limit - md->phys_addr) >> EFI_PAGE_SHIFT;
 			}
-			if (md->num_pages == 0) {
-				printk("efi_memmap_walk: ignoring empty region at 0x%lx",
-				       md->phys_addr);
+
+			if (md->num_pages == 0)
 				continue;
-			}
 
 			curr.start = PAGE_OFFSET + md->phys_addr;
-			curr.end   = curr.start + (md->num_pages << 12);
+			curr.end   = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
 
 			if (!prev_valid) {
 				prev = curr;
@@ -187,10 +289,6 @@
 					prev = curr;
 				}
 			}
-			break;
-
-		      default:
-			continue;
 		}
 	}
 	if (prev_valid) {
@@ -212,8 +310,8 @@
 	void *efi_map_start, *efi_map_end, *p;
 	efi_memory_desc_t *md;
 	u64 efi_desc_size;
-	int pal_code_count=0;
-	u64 mask, flags;
+	int pal_code_count = 0;
+	u64 mask, psr;
 	u64 vaddr;
 
 	efi_map_start = __va(ia64_boot_param->efi_memmap);
@@ -250,25 +348,26 @@
 		 * dedicated ITR for the PAL code.
 		 */
 		if ((vaddr & mask) == (KERNEL_START & mask)) {
-			printk(__FUNCTION__ ": no need to install ITR for PAL code\n");
+			printk("%s: no need to install ITR for PAL code\n", __FUNCTION__);
 			continue;
 		}
 
-		if (md->num_pages << 12 > IA64_GRANULE_SIZE)
+		if (md->num_pages << EFI_PAGE_SHIFT > IA64_GRANULE_SIZE)
 			panic("Woah!  PAL code size bigger than a granule!");
 
 		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
 		printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
-		       smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << 12),
+		       smp_processor_id(), md->phys_addr,
+		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 		       vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
 
 		/*
 		 * Cannot write to CRx with PSR.ic=1
 		 */
-		ia64_clear_ic(flags);
+		psr = ia64_clear_ic();
 		ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask,
 			 pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)), IA64_GRANULE_SHIFT);
-		local_irq_restore(flags);
+		ia64_set_psr(psr);		/* restore psr */
 		ia64_srlz_i();
 	}
 }
@@ -378,7 +477,8 @@
 			md = p;
 			printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
 			       i, md->type, md->attribute, md->phys_addr,
-			       md->phys_addr + (md->num_pages<<12) - 1, md->num_pages >> 8);
+			       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
+			       md->num_pages >> (20 - EFI_PAGE_SHIFT));
 		}
 	}
 #endif
@@ -485,8 +585,50 @@
 	return 0;
 }
 
+u32
+efi_mem_type (unsigned long phys_addr)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	efi_memory_desc_t *md;
+	u64 efi_desc_size;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		md = p;
+
+		if ((md->phys_addr <= phys_addr) && (phys_addr <=
+		    (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1)))
+			 return md->type;
+	}
+	return 0;
+}
+
+u64
+efi_mem_attributes (unsigned long phys_addr)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	efi_memory_desc_t *md;
+	u64 efi_desc_size;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		md = p;
+
+		if ((md->phys_addr <= phys_addr) && (phys_addr <=
+		    (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1)))
+			return md->attribute;
+	}
+	return 0;
+}
+
 static void __exit
-efivars_exit(void)
+efivars_exit (void)
 {
 #ifdef CONFIG_PROC_FS
  	remove_proc_entry(efi_dir->name, NULL);
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/efi_stub.S linux-2.4.20-pre7/arch/ia64/kernel/efi_stub.S
--- linux-2.4.20-pre6/arch/ia64/kernel/efi_stub.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/efi_stub.S	Thu Sep 12 20:01:39 2002
@@ -53,23 +53,21 @@
 	mov loc4=ar.rsc			// save RSE configuration
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	;;
-
 	ld8 gp=[in0]			// load EFI function's global pointer
-	mov out0=in1
-	mov out1=in2
 	movl r16=PSR_BITS_TO_CLEAR
-
 	mov loc3=psr			// save processor status word
 	movl r17=PSR_BITS_TO_SET
 	;;
-	mov out2=in3
 	or loc3=loc3,r17
 	mov b6=r2
 	;;
 	andcm r16=loc3,r16		// get psr with IT, DT, and RT bits cleared
-	mov out3=in4
 	br.call.sptk.many rp=ia64_switch_mode
 .ret0:	mov out4=in5
+	mov out0=in1
+	mov out1=in2
+	mov out2=in3
+	mov out3=in4
 	mov out5=in6
 	mov out6=in7
 	br.call.sptk.many rp=b6		// call the EFI function
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/efivars.c linux-2.4.20-pre7/arch/ia64/kernel/efivars.c
--- linux-2.4.20-pre6/arch/ia64/kernel/efivars.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/efivars.c	Thu Sep 12 20:01:39 2002
@@ -29,6 +29,9 @@
  *
  * Changelog:
  *
+ *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
+ *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
+ *
  *  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>
@@ -62,15 +65,15 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/smp.h>
+#include <linux/efi.h>
 
-#include <asm/efi.h>
 #include <asm/uaccess.h>
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 MODULE_DESCRIPTION("/proc interface to EFI Variables");
 MODULE_LICENSE("GPL");
 
-#define EFIVARS_VERSION "0.04 2002-Feb-12"
+#define EFIVARS_VERSION "0.05 2002-Mar-26"
 
 static int
 efivar_read(char *page, char **start, off_t off,
@@ -141,20 +144,6 @@
 	return len;
 }
 
-
-static void
-uuid_unparse(efi_guid_t *guid, char *out)
-{
-	sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-		guid->data1, guid->data2, guid->data3,
-		guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3],
-		guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
-}
-
-
-
-
-
 /*
  * efivar_create_proc_entry()
  * Requires:
@@ -197,7 +186,7 @@
 	   private variables from another's.         */
 
 	*(short_name + strlen(short_name)) = '-';
-	uuid_unparse(vendor_guid, short_name + strlen(short_name));
+	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
 
 
 	/* Create the entry in proc */
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/entry.S linux-2.4.20-pre7/arch/ia64/kernel/entry.S
--- linux-2.4.20-pre6/arch/ia64/kernel/entry.S	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/entry.S	Thu Sep 12 20:01:39 2002
@@ -3,7 +3,7 @@
  *
  * Kernel entry points.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -667,23 +667,38 @@
 	/*
 	 * To prevent leaking bits between the kernel and user-space,
 	 * we must clear the stacked registers in the "invalid" partition here.
-	 * Not pretty, but at least it's fast (3.34 registers/cycle).
-	 * Architecturally, this loop could go at 4.67 registers/cycle, but that would
-	 * oversubscribe Itanium.
+	 * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium,
+	 * 5 registers/cycle on McKinley).
 	 */
 #	define pRecurse	p6
 #	define pReturn	p7
+#ifdef CONFIG_ITANIUM
 #	define Nregs	10
+#else
+#	define Nregs	14
+#endif
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
 	shr.u loc1=r18,9		// RNaTslots <= dirtySize / (64*8) + 1
 	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
 	;;
+#if 1
+	.align 32		// see comment below about gas bug...
+#endif
 	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
 	shladd in0=loc1,3,r17
 	mov in1=0
+#if 0
+	// gas-2.11.90 is unable to generate a stop bit after .align, which is bad,
+	// because alloc must be at the beginning of an insn-group.
+	.align 32
+#else
+	nop 0
+	nop 0
+	nop 0
+#endif
 	;;
-//	.align 32	// gas-2.11.90 is unable to generate a stop bit after .align
 rse_clear_invalid:
+#ifdef CONFIG_ITANIUM
 	// cycle 0
  { .mii
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
@@ -712,9 +727,31 @@
 	mov loc7=0
 (pReturn) br.ret.sptk.many b6
 }
+#else /* !CONFIG_ITANIUM */
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
+	add out0=-Nregs*8,in0
+	add out1=1,in1			// increment recursion count
+	mov loc1=0
+	mov loc2=0
+	;;
+	mov loc3=0
+	mov loc4=0
+	mov loc9=0
+	mov loc5=0
+	mov loc6=0
+(pRecurse) br.call.sptk.many b6=rse_clear_invalid
+	;;
+	mov loc7=0
+	mov loc8=0
+	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
+	mov loc10=0
+	mov loc11=0
+(pReturn) br.ret.sptk.many b6
+#endif /* !CONFIG_ITANIUM */
 #	undef pRecurse
 #	undef pReturn
-
+	;;
 	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
 	;;
 	loadrs
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/fw-emu.c linux-2.4.20-pre7/arch/ia64/kernel/fw-emu.c
--- linux-2.4.20-pre6/arch/ia64/kernel/fw-emu.c	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/fw-emu.c	Thu Sep 12 20:01:39 2002
@@ -13,14 +13,16 @@
 # include <linux/pci.h>
 #endif
 
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/io.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
 
 #define MB	(1024*1024UL)
+#define GB	(1024*MB)
+#define TB	(1024*GB)
 
-#define NUM_MEM_DESCS	3
+#define NUM_MEM_DESCS	4
 
 static char fw_mem[(  sizeof(struct ia64_boot_param)
 		    + sizeof(efi_system_table_t)
@@ -471,7 +473,7 @@
 	md->phys_addr = 0*MB;
 	md->virt_addr = 0;
 	md->num_pages = (1*MB) >> 12;	/* 1MB (in 4KB pages) */
-	md->attribute = EFI_MEMORY_WB;
+	md->attribute = EFI_MEMORY_WB | EFI_MEMORY_WC | EFI_MEMORY_UC;
 
 	/* fill in a memory descriptor: */
 	md = &efi_memmap[1];
@@ -489,23 +491,16 @@
 	md->phys_addr = 1*MB;
 	md->virt_addr = 1*MB;
 	md->num_pages = (1*MB) >> 12;	/* 1MB (in 4KB pages) */
-	md->attribute = EFI_MEMORY_WB;
-
-#if 0
-	/*
-	 * XXX bootmem is broken for now... (remember to NUM_MEM_DESCS
-	 * if you re-enable this!)
-	 */
+	md->attribute = EFI_MEMORY_WB | EFI_MEMORY_WC | EFI_MEMORY_UC;
 
-	/* descriptor for high memory (>4GB): */
+	/* descriptor for high memory (>4TB): */
 	md = &efi_memmap[3];
 	md->type = EFI_CONVENTIONAL_MEMORY;
 	md->pad = 0;
-	md->phys_addr = 4096*MB;
+	md->phys_addr = 4*TB;
 	md->virt_addr = 0;
-	md->num_pages = (32*MB) >> 12;	/* 32MB (in 4KB pages) */
+	md->num_pages = (64*MB) >> 12;	/* 64MB (in 4KB pages) */
 	md->attribute = EFI_MEMORY_WB;
-#endif
 
 	bp->efi_systab = __pa(&fw_mem);
 	bp->efi_memmap = __pa(efi_memmap);
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/gate.S linux-2.4.20-pre7/arch/ia64/kernel/gate.S
--- linux-2.4.20-pre6/arch/ia64/kernel/gate.S	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/gate.S	Thu Sep 12 20:01:39 2002
@@ -29,7 +29,7 @@
 #	define UNAT_OFF		IA64_SIGCONTEXT_AR_UNAT_OFFSET
 #	define FPSR_OFF		IA64_SIGCONTEXT_AR_FPSR_OFFSET
 #	define PR_OFF		IA64_SIGCONTEXT_PR_OFFSET
-#	define RP_OFF		IA64_SIGCONTEXT_B0_OFFSET
+#	define RP_OFF		IA64_SIGCONTEXT_IP_OFFSET
 #	define SP_OFF		IA64_SIGCONTEXT_R12_OFFSET
 #	define RBS_BASE_OFF	IA64_SIGCONTEXT_RBS_BASE_OFFSET
 #	define LOADRS_OFF	IA64_SIGCONTEXT_LOADRS_OFFSET
@@ -108,7 +108,7 @@
 	dep r8=0,r8,38,26			// clear EC0, CPL0 and reserved bits
 	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
 	;;
-	.spillsp ar.pfs, CFM_OFF
+	.spillsp ar.pfs, CFM_OFF+SIGCONTEXT_OFF
 	st8 [base0]=r8				// save CFM0
 	adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
 	;;
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/head.S linux-2.4.20-pre7/arch/ia64/kernel/head.S
--- linux-2.4.20-pre6/arch/ia64/kernel/head.S	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/head.S	Thu Sep 12 20:01:39 2002
@@ -562,137 +562,114 @@
 END(__ia64_load_fpu)
 
 GLOBAL_ENTRY(__ia64_init_fpu)
-	alloc r2=ar.pfs,0,0,0,0
-	stf.spill [sp]=f0
-	mov      f32=f0
-	;;
-	ldf.fill f33=[sp]
-	ldf.fill f34=[sp]
-	mov      f35=f0
-	;;
-	ldf.fill f36=[sp]
-	ldf.fill f37=[sp]
-	mov      f38=f0
-	;;
-	ldf.fill f39=[sp]
-	ldf.fill f40=[sp]
-	mov      f41=f0
-	;;
-	ldf.fill f42=[sp]
-	ldf.fill f43=[sp]
-	mov      f44=f0
-	;;
-	ldf.fill f45=[sp]
-	ldf.fill f46=[sp]
-	mov      f47=f0
-	;;
-	ldf.fill f48=[sp]
-	ldf.fill f49=[sp]
-	mov      f50=f0
-	;;
-	ldf.fill f51=[sp]
-	ldf.fill f52=[sp]
-	mov      f53=f0
-	;;
-	ldf.fill f54=[sp]
-	ldf.fill f55=[sp]
-	mov      f56=f0
-	;;
-	ldf.fill f57=[sp]
-	ldf.fill f58=[sp]
-	mov      f59=f0
-	;;
-	ldf.fill f60=[sp]
-	ldf.fill f61=[sp]
-	mov      f62=f0
-	;;
-	ldf.fill f63=[sp]
-	ldf.fill f64=[sp]
-	mov      f65=f0
-	;;
-	ldf.fill f66=[sp]
-	ldf.fill f67=[sp]
-	mov      f68=f0
-	;;
-	ldf.fill f69=[sp]
-	ldf.fill f70=[sp]
-	mov      f71=f0
-	;;
-	ldf.fill f72=[sp]
-	ldf.fill f73=[sp]
-	mov      f74=f0
-	;;
-	ldf.fill f75=[sp]
-	ldf.fill f76=[sp]
-	mov      f77=f0
-	;;
-	ldf.fill f78=[sp]
-	ldf.fill f79=[sp]
-	mov      f80=f0
-	;;
-	ldf.fill f81=[sp]
-	ldf.fill f82=[sp]
-	mov      f83=f0
-	;;
-	ldf.fill f84=[sp]
-	ldf.fill f85=[sp]
-	mov      f86=f0
-	;;
-	ldf.fill f87=[sp]
-	ldf.fill f88=[sp]
-	mov      f89=f0
-	;;
-	ldf.fill f90=[sp]
-	ldf.fill f91=[sp]
-	mov      f92=f0
-	;;
-	ldf.fill f93=[sp]
-	ldf.fill f94=[sp]
-	mov      f95=f0
-	;;
-	ldf.fill f96=[sp]
-	ldf.fill f97=[sp]
-	mov      f98=f0
-	;;
-	ldf.fill f99=[sp]
-	ldf.fill f100=[sp]
-	mov      f101=f0
-	;;
-	ldf.fill f102=[sp]
-	ldf.fill f103=[sp]
-	mov      f104=f0
-	;;
-	ldf.fill f105=[sp]
-	ldf.fill f106=[sp]
-	mov      f107=f0
-	;;
-	ldf.fill f108=[sp]
-	ldf.fill f109=[sp]
-	mov      f110=f0
-	;;
-	ldf.fill f111=[sp]
-	ldf.fill f112=[sp]
-	mov      f113=f0
-	;;
-	ldf.fill f114=[sp]
-	ldf.fill f115=[sp]
-	mov      f116=f0
-	;;
-	ldf.fill f117=[sp]
-	ldf.fill f118=[sp]
-	mov      f119=f0
-	;;
-	ldf.fill f120=[sp]
-	ldf.fill f121=[sp]
-	mov      f122=f0
-	;;
-	ldf.fill f123=[sp]
-	ldf.fill f124=[sp]
-	mov      f125=f0
+	stf.spill [sp]=f0		// M3
+	mov	 f32=f0			// F
+	nop.b	 0
+
+	ldfps	 f33,f34=[sp]		// M0
+	ldfps	 f35,f36=[sp]		// M1
+	mov      f37=f0			// F
 	;;
-	ldf.fill f126=[sp]
-	mov      f127=f0
-	br.ret.sptk.many rp
+
+	setf.s	 f38=r0			// M2
+	setf.s	 f39=r0			// M3
+	mov      f40=f0			// F
+
+	ldfps	 f41,f42=[sp]		// M0
+	ldfps	 f43,f44=[sp]		// M1
+	mov      f45=f0			// F
+
+	setf.s	 f46=r0			// M2
+	setf.s	 f47=r0			// M3
+	mov      f48=f0			// F
+
+	ldfps	 f49,f50=[sp]		// M0
+	ldfps	 f51,f52=[sp]		// M1
+	mov      f53=f0			// F
+
+	setf.s	 f54=r0			// M2
+	setf.s	 f55=r0			// M3
+	mov      f56=f0			// F
+
+	ldfps	 f57,f58=[sp]		// M0
+	ldfps	 f59,f60=[sp]		// M1
+	mov      f61=f0			// F
+
+	setf.s	 f62=r0			// M2
+	setf.s	 f63=r0			// M3
+	mov      f64=f0			// F
+
+	ldfps	 f65,f66=[sp]		// M0
+	ldfps	 f67,f68=[sp]		// M1
+	mov      f69=f0			// F
+
+	setf.s	 f70=r0			// M2
+	setf.s	 f71=r0			// M3
+	mov      f72=f0			// F
+
+	ldfps	 f73,f74=[sp]		// M0
+	ldfps	 f75,f76=[sp]		// M1
+	mov      f77=f0			// F
+
+	setf.s	 f78=r0			// M2
+	setf.s	 f79=r0			// M3
+	mov      f80=f0			// F
+
+	ldfps	 f81,f82=[sp]		// M0
+	ldfps	 f83,f84=[sp]		// M1
+	mov      f85=f0			// F
+
+	setf.s	 f86=r0			// M2
+	setf.s	 f87=r0			// M3
+	mov      f88=f0			// F
+
+	/*
+	 * When the instructions are cached, it would be faster to initialize
+	 * the remaining registers with simply mov instructions (F-unit).
+	 * This gets the time down to ~29 cycles.  However, this would use up
+	 * 33 bundles, whereas continuing with the above pattern yields
+	 * 10 bundles and ~30 cycles.
+	 */
+
+	ldfps	 f89,f90=[sp]		// M0
+	ldfps	 f91,f92=[sp]		// M1
+	mov      f93=f0			// F
+
+	setf.s	 f94=r0			// M2
+	setf.s	 f95=r0			// M3
+	mov      f96=f0			// F
+
+	ldfps	 f97,f98=[sp]		// M0
+	ldfps	 f99,f100=[sp]		// M1
+	mov      f101=f0		// F
+
+	setf.s	 f102=r0		// M2
+	setf.s	 f103=r0		// M3
+	mov      f104=f0		// F
+
+	ldfps	 f105,f106=[sp]		// M0
+	ldfps	 f107,f108=[sp]		// M1
+	mov      f109=f0		// F
+
+	setf.s	 f110=r0		// M2
+	setf.s	 f111=r0		// M3
+	mov      f112=f0		// F
+
+	ldfps	 f113,f114=[sp]		// M0
+	ldfps	 f115,f116=[sp]		// M1
+	mov      f117=f0		// F
+
+	setf.s	 f118=r0		// M2
+	setf.s	 f119=r0		// M3
+	mov      f120=f0		// F
+
+	ldfps	 f121,f122=[sp]		// M0
+	ldfps	 f123,f124=[sp]		// M1
+	mov      f125=f0		// F
+
+	setf.s	 f126=r0		// M2
+	setf.s	 f127=r0		// M3
+	br.ret.sptk.many rp		// F
 END(__ia64_init_fpu)
 
 /*
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/ia64_ksyms.c linux-2.4.20-pre7/arch/ia64/kernel/ia64_ksyms.c
--- linux-2.4.20-pre6/arch/ia64/kernel/ia64_ksyms.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/ia64_ksyms.c	Thu Sep 12 20:01:39 2002
@@ -1,11 +1,11 @@
 /*
  * Architecture-specific kernel symbols
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/string.h>
+
 EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcmp);
@@ -148,3 +148,10 @@
 #include <linux/proc_fs.h>
 extern struct proc_dir_entry *efi_dir;
 EXPORT_SYMBOL(efi_dir);
+
+#include <asm/machvec.h>
+#ifdef CONFIG_IA64_GENERIC
+EXPORT_SYMBOL(ia64_mv);
+#endif
+EXPORT_SYMBOL(machvec_noop);
+
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/iosapic.c linux-2.4.20-pre7/arch/ia64/kernel/iosapic.c
--- linux-2.4.20-pre6/arch/ia64/kernel/iosapic.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/iosapic.c	Thu Sep 12 20:01:39 2002
@@ -22,30 +22,44 @@
  * 02/01/07     E. Focht        <efocht@ess.nec.de> Redirectable interrupt vectors in
  *                              iosapic_set_affinity(), initializations for
  *                              /proc/irq/#/smp_affinity
+ * 02/04/02	P. Diefenbaugh	Cleaned up ACPI PCI IRQ routing.
+ * 02/04/18	J.I. Lee	bug fix in iosapic_init_pci_irq
+ * 02/04/30	J.I. Lee	bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping error
+ * 02/07/29	T. Kochi	Allocate interrupt vectors dynamically
+ * 02/08/04	T. Kochi	Cleaned up terminology (irq, global system interrupt, vector, etc.)
+ * 02/08/13	B. Helgaas	Support PCI segments
  */
 /*
  * Here is what the interrupt logic between a PCI device and the CPU looks like:
  *
  * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD).  The
- *     device is uniquely identified by its bus--, and slot-number (the function
+ *     device is uniquely identified by its segment--, bus--, and slot-number (the function
  *     number does not matter here because all functions share the same interrupt
  *     lines).
  *
  * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller.
  *     Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level
- *     triggered and use the same polarity).  Each interrupt line has a unique IOSAPIC
- *     irq number which can be calculated as the sum of the controller's base irq number
- *     and the IOSAPIC pin number to which the line connects.
+ *     triggered and use the same polarity).  Each interrupt line has a unique Global
+ *     System Interrupt (GSI) number which can be calculated as the sum of the controller's
+ *     base GSI number and the IOSAPIC pin number to which the line connects.
  *
- * (3) The IOSAPIC uses an internal table to map the IOSAPIC pin into the IA-64 interrupt
- *     vector.  This interrupt vector is then sent to the CPU.
+ * (3) The IOSAPIC uses internal routing table entries (RTEs) to map the IOSAPIC pin
+ *     to the IA-64 interrupt vector.  This interrupt vector is then sent to the CPU.
  *
- * In other words, there are two levels of indirections involved:
+ * (4) The kernel recognizes an interrupt as an IRQ.  The IRQ interface
+ *     is an architecture-independent interrupt handling mechanism in
+ *     Linux.  An IRQ is a number, so we need a mapping between IRQ
+ *     numbers and IA-64 vectors.  The platform_irq_to_vector(irq) and
+ *     platform_local_vector_to_irq(vector) APIs can define platform-
+ *     specific mappings.
  *
- *	pci pin -> iosapic irq -> IA-64 vector
+ * To sum up, there are three levels of mappings involved:
  *
- * Note: outside this module, IA-64 vectors are called "irqs".  This is because that's
- * the traditional name Linux uses for interrupt vectors.
+ *	PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
+ *
+ * Note: The term "IRQ" is loosely used everywhere in the Linux kernel
+ * to describe interrupts.  In this module, "IRQ" refers only to Linux
+ * IRQ numbers ("isa_irq" is an exception to this rule).
  */
 #include <linux/config.h>
 
@@ -56,9 +70,8 @@
 #include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/irq.h>
+#include <linux/acpi.h>
 
-#include <asm/acpi-ext.h>
-#include <asm/acpikcfg.h>
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
 #include <asm/io.h>
@@ -69,80 +82,103 @@
 #include <asm/system.h>
 
 
-#undef DEBUG_IRQ_ROUTING
-#undef	OVERRIDE_DEBUG
+#undef DEBUG_INTERRUPT_ROUTING
+#undef OVERRIDE_DEBUG
+
+#ifdef DEBUG_INTERRUPT_ROUTING
+#define DBG(fmt...)	printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
 
 static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
 
-/* PCI pin to IOSAPIC irq routing information.  This info typically comes from ACPI. */
+/* PCI pin to GSI routing information.  This info typically comes from ACPI. */
 
 static struct {
 	int num_routes;
 	struct pci_vector_struct *route;
 } pci_irq;
 
-/* This tables maps IA-64 vectors to the IOSAPIC pin that generates this vector. */
+/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
+
+static struct iosapic_intr_info {
+	char		*addr;		/* base address of IOSAPIC */
+	unsigned int	gsi_base;	/* first GSI assigned to this IOSAPIC */
+	char		rte_index;	/* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */
+	unsigned char	dmode	: 3;	/* delivery mode (see iosapic.h) */
+	unsigned char 	polarity: 1;	/* interrupt polarity (see iosapic.h) */
+	unsigned char	trigger	: 1;	/* trigger mode (see iosapic.h) */
+} iosapic_intr_info[IA64_NUM_VECTORS];
+
+static struct iosapic {
+	char		*addr;		/* base address of IOSAPIC */
+	unsigned int 	gsi_base;	/* first GSI assigned to this IOSAPIC */
+	unsigned short 	num_rte;	/* number of RTE in this IOSAPIC */
+	unsigned char	pcat_compat;	/* 8259 compatibility flag */
+} iosapic_lists[256] __devinitdata;
+
+static int __devinitdata num_iosapic = 0;
 
-static struct iosapic_irq {
-	char *addr;			/* base address of IOSAPIC */
-	unsigned char base_irq;		/* first irq assigned to this IOSAPIC */
-	char pin;			/* IOSAPIC pin (-1 => not an IOSAPIC irq) */
-	unsigned char dmode	: 3;	/* delivery mode (see iosapic.h) */
-	unsigned char polarity	: 1;	/* interrupt polarity (see iosapic.h) */
-	unsigned char trigger	: 1;	/* trigger mode (see iosapic.h) */
-} iosapic_irq[IA64_NUM_VECTORS];
 
 /*
- * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector.  If no
- * entry exists, return -1.
+ * Find an IOSAPIC associated with a GSI
  */
-int
-iosapic_irq_to_vector (int irq)
+static inline int __devinit
+find_iosapic (unsigned int gsi)
 {
-	int vector;
+	int i;
 
-	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-		if (iosapic_irq[vector].base_irq + iosapic_irq[vector].pin == irq)
-			return vector;
+	for (i = 0; i < num_iosapic; i++)
+		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
+			return i;
 	return -1;
 }
 
 /*
- * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
- * return -1.
+ * Translate GSI number to the corresponding IA-64 interrupt vector.  If no
+ * entry exists, return -1.
  */
-static int
-pci_pin_to_vector (int bus, int slot, int pci_pin)
+int
+gsi_to_vector (unsigned int gsi)
 {
-	struct pci_vector_struct *r;
+	int vector;
 
-	for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; ++r)
-		if (r->bus == bus && (r->pci_id >> 16) == slot && r->pin == pci_pin)
-			return iosapic_irq_to_vector(r->irq);
+	for (vector = 0; vector < IA64_NUM_VECTORS; vector++)
+		if (iosapic_intr_info[vector].gsi_base + iosapic_intr_info[vector].rte_index == gsi)
+			return vector;
 	return -1;
 }
 
 static void
-set_rte (unsigned int vector, unsigned long dest)
+set_rte (unsigned int vector, unsigned int dest)
 {
 	unsigned long pol, trigger, dmode;
 	u32 low32, high32;
 	char *addr;
-	int pin;
+	int rte_index;
 	char redir;
 
-	pin = iosapic_irq[vector].pin;
-	if (pin < 0)
+	rte_index = iosapic_intr_info[vector].rte_index;
+	if (rte_index < 0)
 		return;		/* not an IOSAPIC interrupt */
 
-	addr    = iosapic_irq[vector].addr;
-	pol     = iosapic_irq[vector].polarity;
-	trigger = iosapic_irq[vector].trigger;
-	dmode   = iosapic_irq[vector].dmode;
+	addr    = iosapic_intr_info[vector].addr;
+	pol     = iosapic_intr_info[vector].polarity;
+	trigger = iosapic_intr_info[vector].trigger;
+	dmode   = iosapic_intr_info[vector].dmode;
 
 	redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
 #ifdef CONFIG_SMP
-	set_irq_affinity_info(vector, (int)(dest & 0xffff), redir);
+	{
+		int irq;
+
+		for (irq = 0; irq < NR_IRQS; ++irq)
+			if (irq_to_vector(irq) == vector) {
+				set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
+				break;
+			}
+	}
 #endif
 
 	low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
@@ -153,9 +189,9 @@
 	/* dest contains both id and eid */
 	high32 = (dest << IOSAPIC_DEST_SHIFT);
 
-	writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT);
+	writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
 	writel(high32, addr + IOSAPIC_WINDOW);
-	writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+	writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 	writel(low32, addr + IOSAPIC_WINDOW);
 }
 
@@ -171,18 +207,18 @@
 	unsigned long flags;
 	char *addr;
 	u32 low32;
-	int pin;
+	int rte_index;
 	ia64_vector vec = irq_to_vector(irq);
 
-	addr = iosapic_irq[vec].addr;
-	pin = iosapic_irq[vec].pin;
+	addr = iosapic_intr_info[vec].addr;
+	rte_index = iosapic_intr_info[vec].rte_index;
 
-	if (pin < 0)
+	if (rte_index < 0)
 		return;			/* not an IOSAPIC interrupt! */
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
 		low32 |= (1 << IOSAPIC_MASK_SHIFT);    /* set only the mask bit */
@@ -197,17 +233,17 @@
 	unsigned long flags;
 	char *addr;
 	u32 low32;
-	int pin;
+	int rte_index;
 	ia64_vector vec = irq_to_vector(irq);
 
-	addr = iosapic_irq[vec].addr;
-	pin = iosapic_irq[vec].pin;
-	if (pin < 0)
+	addr = iosapic_intr_info[vec].addr;
+	rte_index = iosapic_intr_info[vec].rte_index;
+	if (rte_index < 0)
 		return;			/* not an IOSAPIC interrupt! */
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
 		low32 &= ~(1 << IOSAPIC_MASK_SHIFT);    /* clear only the mask bit */
@@ -223,24 +259,28 @@
 #ifdef CONFIG_SMP
 	unsigned long flags;
 	u32 high32, low32;
-	int dest, pin;
+	int dest, rte_index;
 	char *addr;
-	int redir = (irq & (1<<31)) ? 1 : 0;
+	int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
+	ia64_vector vec;
+
+	irq &= (~IA64_IRQ_REDIRECTED);
+	vec = irq_to_vector(irq);
 
 	mask &= (1UL << smp_num_cpus) - 1;
 
-	if (!mask || irq >= IA64_NUM_VECTORS)
+	if (!mask || vec >= IA64_NUM_VECTORS)
 		return;
 
 	dest = cpu_physical_id(ffz(~mask));
 
-	pin = iosapic_irq[irq].pin;
-	addr = iosapic_irq[irq].addr;
+	rte_index = iosapic_intr_info[vec].rte_index;
+	addr = iosapic_intr_info[vec].addr;
 
-	if (pin < 0)
+	if (rte_index < 0)
 		return;			/* not an IOSAPIC interrupt */
 
-	set_irq_affinity_info(irq,dest,redir);
+	set_irq_affinity_info(irq, dest, redir);
 
 	/* dest contains both id and eid */
 	high32 = dest << IOSAPIC_DEST_SHIFT;
@@ -248,7 +288,7 @@
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
 		/* get current delivery mode by reading the low32 */
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
 		low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT);
@@ -259,9 +299,9 @@
 		        /* change delivery mode to fixed */
 			low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
 
-		writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
 		writel(high32, addr + IOSAPIC_WINDOW);
-		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
+		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 		writel(low32, addr + IOSAPIC_WINDOW);
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
@@ -284,7 +324,7 @@
 {
 	ia64_vector vec = irq_to_vector(irq);
 
-	writel(vec, iosapic_irq[vec].addr + IOSAPIC_EOI);
+	writel(vec, iosapic_intr_info[vec].addr + IOSAPIC_EOI);
 }
 
 #define iosapic_shutdown_level_irq	mask_irq
@@ -355,7 +395,7 @@
 	 * {
 	 *	unsigned int version   : 8;
 	 *	unsigned int reserved1 : 8;
-	 *	unsigned int pins      : 8;
+	 *	unsigned int max_redir : 8;
 	 *	unsigned int reserved2 : 8;
 	 * }
 	 */
@@ -372,69 +412,72 @@
 {
 	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)
+	if (iosapic_intr_info[vector].rte_index >= 0 || iosapic_intr_info[vector].addr
+	    || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode
+	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[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;
+		new_vector = ia64_alloc_vector();
+		printk("Reassigning Vector %d to %d\n", vector, new_vector);
+		memcpy (&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
+			sizeof(struct iosapic_intr_info));
+		memset (&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
+		iosapic_intr_info[vector].rte_index = -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)
+register_intr (unsigned int gsi, int vector, unsigned char delivery,
+	       unsigned long polarity, unsigned long edge_triggered,
+	       unsigned int gsi_base, char *iosapic_address)
 {
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
+	int rte_index;
 
-	iosapic_irq[vector].pin	= pin;
-	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
-	iosapic_irq[vector].dmode    = delivery;
+	rte_index = gsi - gsi_base;
+	iosapic_intr_info[vector].rte_index = rte_index;
+	iosapic_intr_info[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
+	iosapic_intr_info[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)
+	 * In override, it may not provide addr/gsi_base.  GSI is enough to
+	 * locate iosapic addr, gsi_base and rte_index by examining
+	 * gsi_base and num_rte of registered iosapics (tbd)
 	 */
 #ifndef	OVERRIDE_DEBUG
 	if (iosapic_address) {
-		iosapic_irq[vector].addr = iosapic_address;
-		iosapic_irq[vector].base_irq = base_irq;
+		iosapic_intr_info[vector].addr = iosapic_address;
+		iosapic_intr_info[vector].gsi_base = gsi_base;
 	}
 #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);
+		if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address))
+			printk("WARN: %s: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n",
+			       __FUNCTION__, gsi, vector);
+		iosapic_intr_info[vector].addr = iosapic_address;
+		if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) {
+			printk("WARN: %s: diff GSI base 0x%x for GSI 0x%x, vector %d\n",
+			       __FUNCTION__, gsi_base, gsi, 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);
+		iosapic_intr_info[vector].gsi_base = gsi_base;
+	} else if (!iosapic_intr_info[vector].addr)
+		printk("WARN: %s: invalid override for GSI 0x%x, vector %d\n",
+		       __FUNCTION__, gsi, vector);
 #endif
 	if (edge_triggered) {
-		iosapic_irq[vector].trigger = IOSAPIC_EDGE;
+		iosapic_intr_info[vector].trigger = IOSAPIC_EDGE;
 		irq_type = &irq_type_iosapic_edge;
 	} else {
-		iosapic_irq[vector].trigger = IOSAPIC_LEVEL;
+		iosapic_intr_info[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("register_irq(): changing vector 0x%02x from "
-			       "%s to %s\n", vector, idesc->handler->typename, irq_type->typename);
+			printk("%s: changing vector %d from %s to %s\n",
+			       __FUNCTION__, vector, idesc->handler->typename,
+			       irq_type->typename);
 		idesc->handler = irq_type;
 	}
 }
@@ -445,24 +488,26 @@
  * program the IOSAPIC RTE.
  */
 int
-iosapic_register_irq (u32 global_vector, unsigned long polarity, unsigned long
-                      edge_triggered, u32 base_irq, char *iosapic_address)
+iosapic_register_intr (unsigned int gsi,
+		       unsigned long polarity, unsigned long edge_triggered,
+		       unsigned int gsi_base, char *iosapic_address)
 {
 	int vector;
+	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
 
-	vector = iosapic_irq_to_vector(global_vector);
+	vector = gsi_to_vector(gsi);
 	if (vector < 0)
-		vector = ia64_alloc_irq();
+		vector = ia64_alloc_vector();
 
-	register_irq (global_vector, vector, global_vector - base_irq,
-			IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
-			base_irq, iosapic_address);
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+		      polarity, edge_triggered, gsi_base, iosapic_address);
 
-	printk("IOSAPIC 0x%x(%s,%s) -> Vector 0x%x\n", global_vector,
-	       (polarity ? "high" : "low"), (edge_triggered ? "edge" : "level"), vector);
+	printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       gsi, (polarity ? "high" : "low"),
+	       (edge_triggered ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
-	set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+	set_rte(vector, dest);
 	return vector;
 }
 
@@ -471,15 +516,17 @@
  * 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,
-			       unsigned long edge_triggered, u32 base_irq, char *iosapic_address)
+iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
+				int iosapic_vector, u16 eid, u16 id,
+				unsigned long polarity, unsigned long edge_triggered,
+				unsigned int gsi_base, char *iosapic_address)
 {
 	unsigned char delivery;
 	int vector;
+	unsigned int dest = ((id << 8) | eid) & 0xffff;
 
 	switch (int_type) {
-	case ACPI20_ENTRY_PIS_PMI:
+	      case ACPI_INTERRUPT_PMI:
 		vector = iosapic_vector;
 		/*
 		 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
@@ -488,223 +535,320 @@
 		iosapic_reassign_vector(vector);
 		delivery = IOSAPIC_PMI;
 		break;
-	case ACPI20_ENTRY_PIS_CPEI:
+	      case ACPI_INTERRUPT_INIT:
+		vector = ia64_alloc_vector();
+		delivery = IOSAPIC_INIT;
+		break;
+	      case ACPI_INTERRUPT_CPEI:
 		vector = IA64_PCE_VECTOR;
 		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
-	case ACPI20_ENTRY_PIS_INIT:
-		vector = ia64_alloc_irq();
-		delivery = IOSAPIC_INIT;
-		break;
-	default:
-		printk("iosapic_register_platform_irq(): invalid int type\n");
+	      default:
+		printk("%s: invalid interrupt type (%d)\n", __FUNCTION__,
+			int_type);
 		return -1;
 	}
 
-	register_irq(global_vector, vector, global_vector - base_irq, delivery, polarity,
-		     edge_triggered, base_irq, iosapic_address);
+	register_intr(gsi, vector, delivery, polarity,
+		      edge_triggered, gsi_base, iosapic_address);
 
-	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);
+	printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       int_type, gsi, (polarity ? "high" : "low"),
+	       (edge_triggered ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
-	set_rte(vector, ((id << 8) | eid) & 0xffff);
+	set_rte(vector, dest);
 	return vector;
 }
 
 
 /*
- * 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 IRQ override.
+ * Note that the gsi_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)
-{
-	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",
-	       (unsigned) irq, (unsigned) pin,
-	       polarity ? "high" : "low", edge_triggered ? "edge" : "level",
-	       vector);
-#endif
+iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
+			  unsigned long polarity, unsigned long edge_triggered)
+{
+	int index, vector;
+	unsigned int gsi_base;
+	char *addr;
+	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
+
+	index = find_iosapic(gsi);
+
+	if (index < 0) {
+		printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi);
+		return;
+	}
+
+	vector = isa_irq_to_vector(isa_irq);
+	addr = iosapic_lists[index].addr;
+	gsi_base = iosapic_lists[index].gsi_base;
+
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
+		      gsi_base, addr);
+
+	DBG("ISA: IRQ %u -> GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	    isa_irq, global_vector,
+	    polarity ? "high" : "low", edge_triggered ? "edge" : "level",
+	    dest, vector);
 
 	/* program the IOSAPIC routing table */
-	set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+	set_rte(vector, dest);
 }
 
-void __init
-iosapic_init (unsigned long phys_addr, unsigned int base_irq, int pcat_compat)
+/*
+ * Map PCI pin to the corresponding GSI.
+ * If no such mapping exists, return -1.
+ */
+static int
+pci_pin_to_gsi (int segment, int bus, int slot, int pci_pin, unsigned int *gsi)
 {
-	int i, irq, max_pin, vector, pin;
-	unsigned int ver;
+	struct pci_vector_struct *r;
+
+	for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; r++)
+		if (r->segment == segment && r->bus == bus &&
+		    (r->pci_id >> 16) == slot && r->pin == pci_pin) {
+			*gsi = r->irq;
+			return 0;
+		}
+
+	return -1;
+}
+
+/*
+ * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
+ * try to allocate a new vector.  If it fails, return -1.
+ */
+static int
+pci_pin_to_vector (int segment, int bus, int slot, int pci_pin)
+{
+	int index, vector;
+	int gsi_base, pcat_compat;
+	char *addr;
+	unsigned int gsi;
+
+	if (pci_pin_to_gsi(segment, bus, slot, pci_pin, &gsi) < 0) {
+		printk("PCI: no interrupt route for %02x:%02x:%02x pin %c\n",
+			segment, bus, slot, 'A' + pci_pin);
+		return -1;
+	}
+
+	vector = gsi_to_vector(gsi);
+
+	if (vector < 0) {
+		/* we should allocate a vector for this interrupt line */
+
+		index = find_iosapic(gsi);
+
+		if (index < 0) {
+			printk("PCI: GSI 0x%x has no IOSAPIC mapping\n", gsi);
+			return -1;
+		}
+
+		addr = iosapic_lists[index].addr;
+		gsi_base = iosapic_lists[index].gsi_base;
+		pcat_compat = iosapic_lists[index].pcat_compat;
+
+		if (pcat_compat && (gsi < 16))
+			vector = isa_irq_to_vector(gsi);
+		else {
+			/* new GSI; allocate a vector for it */
+			vector = ia64_alloc_vector();
+		}
+
+		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
+			      0, 0, gsi_base, addr);
+
+		DBG("PCI: (%02x:%02x:%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n",
+		    segment, bus, slot, 'A' + pci_pin, gsi, vector);
+	}
+
+	return vector;
+}
+
+void __devinit
+iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
+{
+	int num_rte, vector;
+	unsigned int isa_irq, ver;
 	char *addr;
 	static int first_time = 1;
 
 	if (first_time) {
 		first_time = 0;
-
 		for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-			iosapic_irq[vector].pin = -1;	/* mark as unused */
+			iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
+	}
 
+	if (pcat_compat) {
 		/*
-		 * Fetch the PCI interrupt routing table:
+		 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
+		 * enabled.
 		 */
-		acpi_cf_get_pci_vectors(&pci_irq.route, &pci_irq.num_routes);
+		printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
+		outb(0xff, 0xA1);
+		outb(0xff, 0x21);
 	}
 
 	addr = ioremap(phys_addr, 0);
 	ver = iosapic_version(addr);
-	max_pin = (ver >> 16) & 0xff;
 
-	printk("IOSAPIC: version %x.%x, address 0x%lx, IRQs 0x%02x-0x%02x\n",
-	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, base_irq, base_irq + max_pin);
+	/*
+	 * The MAX_REDIR register holds the highest input pin
+	 * number (starting from 0).
+	 * We add 1 so that we can use it for number of pins (= RTEs)
+	 */
+	num_rte = ((ver >> 16) & 0xff) + 1;
+
+	iosapic_lists[num_iosapic].addr = addr;
+	iosapic_lists[num_iosapic].pcat_compat = pcat_compat;
+	iosapic_lists[num_iosapic].gsi_base = gsi_base;
+	iosapic_lists[num_iosapic].num_rte = num_rte;
+	num_iosapic++;
+
+	printk("IOSAPIC: version %x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
+	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1);
+
+	if ((gsi_base == 0) && pcat_compat) {
+		unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
 
-	if ((base_irq == 0) && pcat_compat)
 		/*
 		 * Map the legacy ISA devices into the IOSAPIC data.  Some of these may
 		 * get reprogrammed later on with data from the ACPI Interrupt Source
 		 * Override table.
 		 */
-		for (irq = 0; irq < 16; ++irq) {
-			vector = isa_irq_to_vector(irq);
-			if ((pin = iosapic_irq[vector].pin) == -1)
-				pin = irq;
+		for (isa_irq = 0; isa_irq < 16; ++isa_irq) {
+			vector = isa_irq_to_vector(isa_irq);
 
-			register_irq(irq, vector, pin,
+			register_intr(isa_irq, vector, IOSAPIC_LOWEST_PRIORITY,
 				     /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */
-				     IOSAPIC_LOWEST_PRIORITY, 1, 1, base_irq, addr);
+				     1, 1, gsi_base, 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
+			DBG("ISA: IRQ %u -> GSI 0x%x (high,edge) -> CPU 0x%04x vector %d\n",
+			    isa_irq, isa_irq, dest, vector);
 
 			/* program the IOSAPIC routing table: */
-			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+			set_rte(vector, dest);
 		}
+	}
+}
 
-	for (i = 0; i < pci_irq.num_routes; i++) {
-		irq = pci_irq.route[i].irq;
 
-		if ((irq < (int)base_irq) || (irq > (int)(base_irq + max_pin)))
-			/* the interrupt route is for another controller... */
-			continue;
+/*
+ * Set allocated interrupt vector to dev->irq and
+ * program IOSAPIC to deliver interrupts
+ */
+void
+iosapic_fixup_pci_interrupt (struct pci_dev *dev)
+{
+	int segment;
+	unsigned char pci_pin;
+	int vector;
+	unsigned int dest;
+	struct hw_interrupt_type *irq_type;
+	irq_desc_t *idesc;
 
-		if (pcat_compat && (irq < 16))
-			vector = isa_irq_to_vector(irq);
-		else {
-			vector = iosapic_irq_to_vector(irq);
-			if (vector < 0)
-				/* new iosapic irq: allocate a vector for it */
-				vector = ia64_alloc_irq();
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pci_pin);
+	if (pci_pin) {
+		pci_pin--; /* interrupt pins are numberd starting from 1 */
+
+		segment = PCI_SEGMENT(dev);
+		vector = pci_pin_to_vector(segment, dev->bus->number, PCI_SLOT(dev->devfn), pci_pin);
+
+		if (vector < 0 && dev->bus->parent) {
+			/* go back to the bridge */
+			struct pci_dev *bridge = dev->bus->self;
+
+			if (bridge) {
+				/* allow for multiple bridges on an adapter */
+				do {
+					/* do the bridge swizzle... */
+					pci_pin = (pci_pin + PCI_SLOT(dev->devfn)) % 4;
+					vector = pci_pin_to_vector(segment,
+								   bridge->bus->number,
+								   PCI_SLOT(bridge->devfn),
+								   pci_pin);
+				} while (vector < 0 && (bridge = bridge->bus->self));
+			}
+			if (vector >= 0)
+				printk(KERN_WARNING
+				       "PCI: using PPB (%s INT%c) to get vector %d\n",
+				       dev->slot_name, 'A' + pci_pin,
+				       vector);
+			else
+				printk(KERN_WARNING
+				       "PCI: Couldn't map irq for (%s INT%c)\n",
+				       dev->slot_name, 'A' + pci_pin);
 		}
 
-		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
+		if (vector >= 0) {
+			dev->irq = vector;
 
-			/* program the IOSAPIC routing table: */
-			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+			irq_type = &irq_type_iosapic_level;
+			idesc = irq_desc(vector);
+			if (idesc->handler != irq_type) {
+				if (idesc->handler != &no_irq_type)
+					printk("%s: changing vector %d from %s to %s\n",
+					       __FUNCTION__, vector,
+					       idesc->handler->typename,
+					       irq_type->typename);
+				idesc->handler = irq_type;
+			}
+#ifdef CONFIG_SMP
+			/*
+			 * For platforms that do not support interrupt redirect
+			 * via the XTP interface, we can round-robin the PCI
+			 * device interrupts to the processors
+			 */
+			if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
+				static int cpu_index = 0;
+
+				dest = cpu_physical_id(cpu_index) & 0xffff;
+
+				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.
+				 */
+				dest = (ia64_get_lid() >> 16) & 0xffff;
+			}
+#else
+			/* direct the interrupt vector to the running cpu id */
+			dest = (ia64_get_lid() >> 16) & 0xffff;
+#endif
+
+			printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
+			       dev->slot_name, 'A' + pci_pin, dest, vector);
+			set_rte(vector, dest);
+		}
 	}
 }
 
+
 void
 iosapic_pci_fixup (int phase)
 {
 	struct	pci_dev	*dev;
-	unsigned char pin;
-	int vector;
-	struct hw_interrupt_type *irq_type;
-	irq_desc_t *idesc;
+
+	if (phase == 0) {
+		if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) {
+			printk("%s: acpi_get_prt failed\n", __FUNCTION__);
+		}
+		return;
+	}
 
 	if (phase != 1)
 		return;
 
 	pci_for_each_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-		if (pin) {
-			pin--;          /* interrupt pins are numbered starting from 1 */
-			vector = pci_pin_to_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-			if (vector < 0 && dev->bus->parent) {
-				/* go back to the bridge */
-				struct pci_dev *bridge = dev->bus->self;
-
-				if (bridge) {
-					/* allow for multiple bridges on an adapter */
-					do {
-						/* do the bridge swizzle... */
-						pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-						vector = pci_pin_to_vector(bridge->bus->number,
-									   PCI_SLOT(bridge->devfn),
-									   pin);
-					} while (vector < 0 && (bridge = bridge->bus->self));
-				}
-				if (vector >= 0)
-					printk(KERN_WARNING
-					       "PCI: using PPB(B%d,I%d,P%d) to get vector %02x\n",
-					       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)\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
-				 * via the XTP interface, we can round-robin the PCI
-				 * device interrupts to the processors
-				 */
-				if (!(smp_int_redirect & SMP_IRQ_REDIRECTION)) {
-					static int cpu_index = 0;
+		/* fixup dev->irq and program IOSAPIC */
+		iosapic_fixup_pci_interrupt(dev);
 
-					set_rte(vector, cpu_physical_id(cpu_index) & 0xffff);
-
-					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
-			}
-		}
 		/*
 		 * Nothing to fixup
 		 * Fix out-of-range IRQ numbers
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/irq.c linux-2.4.20-pre7/arch/ia64/kernel/irq.c
--- linux-2.4.20-pre6/arch/ia64/kernel/irq.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/irq.c	Thu Sep 12 20:01:39 2002
@@ -67,6 +67,27 @@
 irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { IRQ_DISABLED, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
+#ifdef CONFIG_IA64_GENERIC
+struct irq_desc *
+__ia64_irq_desc (unsigned int irq)
+{
+	return _irq_desc + irq;
+}
+
+ia64_vector
+__ia64_irq_to_vector (unsigned int irq)
+{
+	return (ia64_vector) irq;
+}
+
+unsigned int
+__ia64_local_vector_to_irq (ia64_vector vec)
+{
+	return (unsigned int) vec;
+}
+
+#endif
+
 static void register_irq_proc (unsigned int irq);
 
 /*
@@ -1144,7 +1165,7 @@
 	if (!(new_value & cpu_online_map))
 		return -EINVAL;
 
-	irq_desc(irq)->handler->set_affinity(irq | (redir?(1<<31):0), new_value);
+	irq_desc(irq)->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED :0), new_value);
 
 	return full_count;
 }
@@ -1180,7 +1201,7 @@
 {
 	char name [MAX_NAMELEN];
 
-	if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type))
+	if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type) || irq_dir[irq])
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/irq_ia64.c linux-2.4.20-pre7/arch/ia64/kernel/irq_ia64.c
--- linux-2.4.20-pre6/arch/ia64/kernel/irq_ia64.c	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/irq_ia64.c	Thu Sep 12 20:01:39 2002
@@ -36,6 +36,10 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_PERFMON
+# include <asm/perfmon.h>
+#endif
+
 #define IRQ_DEBUG	0
 
 /* default base addr of IPI table */
@@ -51,14 +55,14 @@
 };
 
 int
-ia64_alloc_irq (void)
+ia64_alloc_vector (void)
 {
-	static int next_irq = IA64_FIRST_DEVICE_VECTOR;
+	static int next_vector = IA64_FIRST_DEVICE_VECTOR;
 
-	if (next_irq > IA64_LAST_DEVICE_VECTOR)
+	if (next_vector > IA64_LAST_DEVICE_VECTOR)
 		/* XXX could look for sharable vectors instead of panic'ing... */
-		panic("ia64_alloc_irq: out of interrupt vectors!");
-	return next_irq++;
+		panic("%s: out of interrupt vectors!", __FUNCTION__);
+	return next_vector++;
 }
 
 extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs);
@@ -173,6 +177,9 @@
 #ifdef CONFIG_SMP
 	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
 #endif
+#ifdef CONFIG_PERFMON
+	perfmon_init_percpu();
+#endif
 	platform_irq_init();
 }
 
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/ivt.S linux-2.4.20-pre7/arch/ia64/kernel/ivt.S
--- linux-2.4.20-pre6/arch/ia64/kernel/ivt.S	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/ivt.S	Thu Sep 12 20:01:39 2002
@@ -126,7 +126,7 @@
 	;;
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
 	srlz.d					// ensure "rsm psr.dt" has taken effect
-(p6)	movl r19=__pa(SWAPPER_PGD_ADDR)		// region 5 is rooted at swapper_pg_dir
+(p6)	movl r19=__pa(swapper_pg_dir)		// region 5 is rooted at swapper_pg_dir
 (p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
 	;;
@@ -329,12 +329,15 @@
 (p8)	br.cond.dptk dtlb_fault
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
+	and r22=IA64_ISR_CODE_MASK,r20		// get the isr.code field
 	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
+	shr.u r18=r16,57			// move address bit 61 to bit 4
+	and r19=r19,r16				// clear ed, reserved bits, and PTE control bits
+	tbit.nz p9,p0=r20,IA64_ISR_NA_BIT	// is non-access bit on?
 	;;
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	cmp.ne p8,p0=r0,r23
+(p9)	cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22	// check isr.code field
 (p8)	br.cond.spnt page_fault
 
 	dep r21=-1,r21,IA64_PSR_ED_BIT,1
@@ -412,7 +415,7 @@
 	;;
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
 	srlz.d
-(p6)	movl r19=__pa(SWAPPER_PGD_ADDR)		// region 5 is rooted at swapper_pg_dir
+(p6)	movl r19=__pa(swapper_pg_dir)		// region 5 is rooted at swapper_pg_dir
 (p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
 	;;
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/mca.c linux-2.4.20-pre7/arch/ia64/kernel/mca.c
--- linux-2.4.20-pre6/arch/ia64/kernel/mca.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/mca.c	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,9 @@
  * Purpose:	Generic MCA handling layer
  *
  * Updated for latest kernel
+ * Copyright (C) 2002 Dell Computer Corporation
+ * Copyright (C) Matt Domsch (Matt_Domsch@dell.com)
+ *
  * Copyright (C) 2002 Intel
  * Copyright (C) Jenna Hall (jenna.s.hall@intel.com)
  *
@@ -15,6 +18,8 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
+ * 02/03/25 M. Domsch	GUID cleanups
+ *
  * 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
@@ -36,6 +41,7 @@
 #include <linux/irq.h>
 #include <linux/smp_lock.h>
 #include <linux/bootmem.h>
+#include <linux/acpi.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
@@ -46,7 +52,6 @@
 
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
-#include <asm/acpi-ext.h>
 
 #undef MCA_PRT_XTRA_DATA
 
@@ -348,17 +353,15 @@
 verify_guid (efi_guid_t *test, efi_guid_t *target)
 {
 	int     rc;
+#ifdef IA64_MCA_DEBUG_INFO
+	char out[40];
+#endif
 
-	if ((rc = memcmp((void *)test, (void *)target, sizeof(efi_guid_t)))) {
-		IA64_MCA_DEBUG("ia64_mca_print: invalid guid = "
-			       "{ %08x, %04x, %04x, { %#02x, %#02x, %#02x, %#02x, "
-			       "%#02x, %#02x, %#02x, %#02x, } } \n ",
-			       test->data1, test->data2, test->data3, test->data4[0],
-			       test->data4[1], test->data4[2], test->data4[3],
-			       test->data4[4], test->data4[5], test->data4[6],
-			       test->data4[7]);
+	if ((rc = efi_guidcmp(*test, *target))) {
+		IA64_MCA_DEBUG(KERN_DEBUG
+			       "verify_guid: invalid GUID = %s\n",
+			       efi_guid_unparse(test, out));
 	}
-
 	return rc;
 }
 
@@ -496,7 +499,7 @@
 	{
 		irq_desc_t *desc;
 		unsigned int irq;
-		int cpev = acpi_request_vector(ACPI20_ENTRY_PIS_CPEI);
+		int cpev = acpi_request_vector(ACPI_INTERRUPT_CPEI);
 
 		if (cpev >= 0) {
 			for (irq = 0; irq < NR_IRQS; ++irq)
@@ -856,11 +859,8 @@
 void
 ia64_log_prt_guid (efi_guid_t *p_guid, prfunc_t prfunc)
 {
-	printk("GUID = { %08x, %04x, %04x, { %#02x, %#02x, %#02x, %#02x, "
-	       "%#02x, %#02x, %#02x, %#02x, } } \n ", p_guid->data1,
-	       p_guid->data2, p_guid->data3, p_guid->data4[0], p_guid->data4[1],
-	       p_guid->data4[2], p_guid->data4[3], p_guid->data4[4],
-	       p_guid->data4[5], p_guid->data4[6], p_guid->data4[7]);
+	char out[40];
+	printk(KERN_DEBUG "GUID = %s\n", efi_guid_unparse(p_guid, out));
 }
 
 static void
@@ -1754,7 +1754,7 @@
 		ia64_log_prt_section_header(slsh, prfunc);
 #endif  // MCA_PRT_XTRA_DATA for test only @FVL
 
-		if (verify_guid((void *)&slsh->guid, (void *)&(SAL_PROC_DEV_ERR_SECT_GUID))) {
+		if (verify_guid(&slsh->guid, &(SAL_PROC_DEV_ERR_SECT_GUID))) {
 			IA64_MCA_DEBUG("ia64_mca_log_print: unsupported record section\n");
 			continue;
 		}
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/mca_asm.S linux-2.4.20-pre7/arch/ia64/kernel/mca_asm.S
--- linux-2.4.20-pre6/arch/ia64/kernel/mca_asm.S	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/mca_asm.S	Thu Sep 12 20:01:39 2002
@@ -684,9 +684,9 @@
 	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
+	dep	r8=0,r8,61,3;;		// convert SAL VA to PA
 	ld8	r1=[r7];;		// set new (ia64_sal) gp
-	DATA_VA_TO_PA(r1)		// convert to physical address
+	dep	r1=0,r1,61,3;;		// convert SAL VA to PA
 	mov	b6=r8
 
 	alloc	r5=ar.pfs,8,0,8,0;;	// allocate stack frame for SAL call
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/minstate.h linux-2.4.20-pre7/arch/ia64/kernel/minstate.h
--- linux-2.4.20-pre6/arch/ia64/kernel/minstate.h	Tue Jul 31 10:30:08 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/minstate.h	Thu Sep 12 20:01:39 2002
@@ -92,7 +92,6 @@
  *
  * Assumed state upon entry:
  *	psr.ic: off
- *	psr.dt: off
  *	r31:	contains saved predicates (pr)
  *
  * Upon exit, the state is as follows:
@@ -186,7 +185,6 @@
  *
  * Assumed state upon entry:
  *	psr.ic: on
- *	psr.dt: on
  *	r2:	points to &pt_regs.r16
  *	r3:	points to &pt_regs.r17
  */
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/pal.S linux-2.4.20-pre7/arch/ia64/kernel/pal.S
--- linux-2.4.20-pre6/arch/ia64/kernel/pal.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/pal.S	Thu Sep 12 20:01:39 2002
@@ -114,7 +114,7 @@
 	;;
 	rsm psr.i
 	mov b7 = loc2
-	;; 
+	;;
 	br.call.sptk.many rp=b7		// now make the call
 .ret0:	mov psr.l  = loc3
 	mov ar.pfs = loc1
@@ -161,7 +161,7 @@
 	;;
 	mov loc3 = psr			// save psr
 	adds r8  = 1f-1b,r8		// calculate return address for call
-	;; 
+	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
 	dep.z r8=r8,0,61		// convert rp to physical
@@ -216,7 +216,7 @@
 	mov out3 = in3		// copy arg3
 	;;
 	mov loc3 = psr		// save psr
-	;; 
+	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
 	;;
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/palinfo.c linux-2.4.20-pre7/arch/ia64/kernel/palinfo.c
--- linux-2.4.20-pre6/arch/ia64/kernel/palinfo.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/palinfo.c	Thu Sep 12 20:01:39 2002
@@ -21,10 +21,10 @@
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/efi.h>
 
 #include <asm/pal.h>
 #include <asm/sal.h>
-#include <asm/efi.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #ifdef CONFIG_SMP
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/pci.c linux-2.4.20-pre7/arch/ia64/kernel/pci.c
--- linux-2.4.20-pre6/arch/ia64/kernel/pci.c	Fri Dec 21 09:41:53 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/pci.c	Thu Sep 12 20:01:39 2002
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/acpi.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
@@ -42,104 +43,256 @@
 extern void ia64_mca_check_errors( void );
 #endif
 
+struct pci_fixup pcibios_fixups[1];
+
+struct pci_ops *pci_root_ops;
+
+int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
+int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
+
+
 /*
- * This interrupt-safe spinlock protects all accesses to PCI
- * configuration space.
+ * Low-level SAL-based PCI configuration access functions. Note that SAL
+ * calls are already serialized (via sal_lock), so we don't need another
+ * synchronization mechanism here.
  */
-static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
 
-struct pci_fixup pcibios_fixups[] = {
-	{ 0 }
-};
+#define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) \
+	((u64)(seg << 24) | (u64)(bus << 16) | \
+	 (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
+
+static int
+pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+{
+	int result = 0;
+	u64 data = 0;
+
+	if (!value || (seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
 
-/* Macro to build a PCI configuration address to be passed as a parameter to SAL. */
+	result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data);
 
-#define PCI_CONFIG_ADDRESS(dev, where) \
-	(((u64) dev->bus->number << 16) | ((u64) (dev->devfn & 0xff) << 8) | (where & 0xff))
+	*value = (u32) data;
+
+	return result;
+}
 
 static int
-pci_conf_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
 {
-	s64 status;
-	u64 lval;
+	if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
+}
+
+
+static int
+pci_sal_read_config_byte (struct pci_dev *dev, int where, u8 *value)
+{
+	int result = 0;
+	u32 data = 0;
+
+	if (!value)
+		return -EINVAL;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 1, &lval);
-	*value = lval;
-	return status;
+	result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			      PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8) data;
+
+	return result;
 }
 
 static int
-pci_conf_read_config_word(struct pci_dev *dev, int where, u16 *value)
+pci_sal_read_config_word (struct pci_dev *dev, int where, u16 *value)
 {
-	s64 status;
-	u64 lval;
+	int result = 0;
+	u32 data = 0;
+
+	if (!value)
+		return -EINVAL;
+
+	result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			      PCI_FUNC(dev->devfn), where, 2, &data);
+
+	*value = (u16) data;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 2, &lval);
-	*value = lval;
-	return status;
+	return result;
 }
 
 static int
-pci_conf_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+pci_sal_read_config_dword (struct pci_dev *dev, int where, u32 *value)
 {
-	s64 status;
-	u64 lval;
+	if (!value)
+		return -EINVAL;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 4, &lval);
-	*value = lval;
-	return status;
+	return pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			    PCI_FUNC(dev->devfn), where, 4, value);
 }
 
 static int
-pci_conf_write_config_byte (struct pci_dev *dev, int where, u8 value)
+pci_sal_write_config_byte (struct pci_dev *dev, int where, u8 value)
 {
-	return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 1, value);
+	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			     PCI_FUNC(dev->devfn), where, 1, value);
 }
 
 static int
-pci_conf_write_config_word (struct pci_dev *dev, int where, u16 value)
+pci_sal_write_config_word (struct pci_dev *dev, int where, u16 value)
 {
-	return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 2, value);
+	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			     PCI_FUNC(dev->devfn), where, 2, value);
 }
 
 static int
-pci_conf_write_config_dword (struct pci_dev *dev, int where, u32 value)
+pci_sal_write_config_dword (struct pci_dev *dev, int where, u32 value)
 {
-	return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 4, value);
+	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
+			     PCI_FUNC(dev->devfn), where, 4, value);
 }
 
-struct pci_ops pci_conf = {
-      pci_conf_read_config_byte,
-      pci_conf_read_config_word,
-      pci_conf_read_config_dword,
-      pci_conf_write_config_byte,
-      pci_conf_write_config_word,
-      pci_conf_write_config_dword
+struct pci_ops pci_sal_ops = {
+	pci_sal_read_config_byte,
+	pci_sal_read_config_word,
+	pci_sal_read_config_dword,
+	pci_sal_write_config_byte,
+	pci_sal_write_config_word,
+	pci_sal_write_config_dword
 };
 
+
 /*
  * Initialization. Uses the SAL interface
  */
+
+static struct pci_controller *
+alloc_pci_controller(int seg)
+{
+	struct pci_controller *controller;
+
+	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return NULL;
+
+	memset(controller, 0, sizeof(*controller));
+	controller->segment = seg;
+	return controller;
+}
+
+static struct pci_bus *
+scan_root_bus(int bus, struct pci_ops *ops, void *sysdata)
+{
+	struct pci_bus *b;
+
+	/*
+	 * We know this is a new root bus we haven't seen before, so
+	 * scan it, even if we've seen the same bus number in a different
+	 * segment.
+	 */
+	b = kmalloc(sizeof(*b), GFP_KERNEL);
+	if (!b)
+		return NULL;
+
+	memset(b, 0, sizeof(*b));
+	INIT_LIST_HEAD(&b->children);
+	INIT_LIST_HEAD(&b->devices);
+
+	list_add_tail(&b->node, &pci_root_buses);
+
+	b->number = b->secondary = bus;
+	b->resource[0] = &ioport_resource;
+	b->resource[1] = &iomem_resource;
+
+	b->sysdata = sysdata;
+	b->ops = ops;
+	b->subordinate = pci_do_scan_bus(b);
+
+	return b;
+}
+
+struct pci_bus *
+pcibios_scan_root(void *handle, int seg, int bus)
+{
+	struct pci_controller *controller;
+	u64 base, size, offset;
+
+	printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus);
+
+	controller = alloc_pci_controller(seg);
+	if (!controller)
+		return NULL;
+
+	controller->acpi_handle = handle;
+
+	acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset);
+	controller->mem_offset = offset;
+
+	return scan_root_bus(bus, pci_root_ops, controller);
+}
+
+void __init
+pcibios_config_init (void)
+{
+	if (pci_root_ops)
+		return;
+
+	printk("PCI: Using SAL to access configuration space\n");
+
+	pci_root_ops = &pci_sal_ops;
+	pci_config_read = pci_sal_read;
+	pci_config_write = pci_sal_write;
+
+	return;
+}
+
 void __init
 pcibios_init (void)
 {
 #	define PCI_BUSES_TO_SCAN 255
-	int i;
+	int i = 0;
+	struct pci_controller *controller;
 
 #ifdef CONFIG_IA64_MCA
 	ia64_mca_check_errors();    /* For post-failure MCA error logging */
 #endif
 
-	platform_pci_fixup(0);	/* phase 0 initialization (before PCI bus has been scanned) */
+	pcibios_config_init();
+
+	platform_pci_fixup(0);	/* phase 0 fixups (before buses scanned) */
 
 	printk("PCI: Probing PCI hardware\n");
-	for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
-		pci_scan_bus(i, &pci_conf, NULL);
+	controller = alloc_pci_controller(0);
+	if (controller)
+		for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
+			pci_scan_bus(i, pci_root_ops, controller);
+
+	platform_pci_fixup(1);	/* phase 1 fixups (after buses scanned) */
 
-	platform_pci_fixup(1);	/* phase 1 initialization (after PCI bus has been scanned) */
 	return;
 }
 
+static void __init
+pcibios_fixup_resource(struct resource *res, u64 offset)
+{
+	res->start += offset;
+	res->end += offset;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		if (!dev->resource[i].start)
+			continue;
+		if (dev->resource[i].flags & IORESOURCE_MEM)
+			pcibios_fixup_resource(&dev->resource[i],
+				PCI_CONTROLLER(dev)->mem_offset);
+	}
+}
+
 /*
  *  Called after each bus is probed, but before its children
  *  are examined.
@@ -147,7 +300,10 @@
 void __init
 pcibios_fixup_bus (struct pci_bus *b)
 {
-	return;
+	struct list_head *ln;
+
+	for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
+		pcibios_fixup_device_resources(pci_dev_b(ln), b);
 }
 
 void __init
@@ -186,7 +342,39 @@
 int
 pcibios_enable_device (struct pci_dev *dev)
 {
-	/* Not needed, since we enable all devices at startup.  */
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	if (!dev)
+		return -EINVAL;
+
+ 	platform_pci_enable_device(dev);
+
+	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);
+	}
+
+	printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name);
+
 	return 0;
 }
 
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/perfmon.c linux-2.4.20-pre7/arch/ia64/kernel/perfmon.c
--- linux-2.4.20-pre6/arch/ia64/kernel/perfmon.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/perfmon.c	Thu Sep 12 20:01:39 2002
@@ -23,6 +23,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wrapper.h>
 #include <linux/mm.h>
+#include <linux/sysctl.h>
 
 #include <asm/bitops.h>
 #include <asm/errno.h>
@@ -42,7 +43,7 @@
  * you must enable the following flag to activate the support for
  * accessing the registers via the perfmonctl() interface.
  */
-#ifdef CONFIG_ITANIUM
+#if defined(CONFIG_ITANIUM) || defined(CONFIG_MCKINLEY)
 #define PFM_PMU_USES_DBR	1
 #endif
 
@@ -68,26 +69,27 @@
 #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)
 
+/* i assume unsigned */
 #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)
+/* XXX: these three assume that register i is implemented */
+#define PMD_IS_COUNTING(i) (pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING)
+#define PMC_IS_COUNTING(i) (pmu_conf.pmc_desc[i].type == PFM_REG_COUNTING)
+#define PMC_IS_MONITOR(c)  (pmu_conf.pmc_desc[i].type == PFM_REG_MONITOR)
 
+/* k assume unsigned */
 #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)
+/* XXX: does not support more than 64 PMDs */
+#define CTX_USED_PMD(ctx, mask) (ctx)->ctx_used_pmds[0] |= (mask)
+#define CTX_IS_USED_PMD(ctx, c) (((ctx)->ctx_used_pmds[0] & (1UL << (c))) != 0UL)
+
 
 #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)
@@ -104,17 +106,29 @@
 
 #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
 
+#ifdef CONFIG_SMP
+#define cpu_is_online(i) (cpu_online_map & (1UL << i))
+#else
+#define cpu_is_online(i)        (i==0)
+#endif
+
 /*
  * debugging
  */
 #define DBprintk(a) \
 	do { \
-		if (pfm_debug_mode >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+		if (pfm_sysctl.debug >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+	} while (0)
+
+#define DBprintk_ovfl(a) \
+	do { \
+		if (pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
 	} while (0)
 
 
+
 /* 
- * These are some helpful architected PMC and IBR/DBR register layouts
+ * Architected PMC structure
  */
 typedef struct {
 	unsigned long pmc_plm:4;	/* privilege level mask */
@@ -139,41 +153,40 @@
 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 */
+	int			psb_flags;	/* bitvector of flags (not yet used) */
 
 	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 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;
 
+/*
+ * psb_flags
+ */
+#define PSB_HAS_VMA	0x1		/* a virtual mapping for the buffer exists */
+
 #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
- * a description of the PMU main characteristic as indicated
- * by PAL
+ * The possible type of a PMU register
  */
-typedef struct {
-	unsigned long pfm_is_disabled;	/* indicates if perfmon is working properly */
-	unsigned long perf_ovfl_val;	/* overflow value for generic counters   */
-	unsigned long max_counters;	/* upper limit on counter pair (PMC/PMD) */
-	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;
+typedef enum { 
+	PFM_REG_NOTIMPL, /* not implemented */
+	PFM_REG_NONE, 	 /* end marker */
+	PFM_REG_MONITOR, /* a PMC with a pmc.pm field only */
+	PFM_REG_COUNTING,/* a PMC with a pmc.pm AND pmc.oi, a PMD used as a counter */
+	PFM_REG_CONTROL, /* PMU control register */
+	PFM_REG_CONFIG,  /* refine configuration */
+	PFM_REG_BUFFER	 /* PMD used as buffer */
+} pfm_pmu_reg_type_t;
 
 /*
  * 64-bit software counter structure
@@ -221,9 +234,11 @@
 
 	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 PMD used                 */
+	unsigned long		ctx_reload_pmds[4];	/* bitmask of PMD to reload on ctxsw   */
+
+	unsigned long		ctx_used_pmcs[4];	/* bitmask PMC used by context         */
+	unsigned long		ctx_reload_pmcs[4];	/* bitmask of PMC to reload on 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) */
@@ -235,6 +250,7 @@
 	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_is_busy;		/* context accessed by overflow handler */
 	atomic_t		ctx_last_cpu;		/* CPU id of current or last CPU used */
 } pfm_context_t;
 
@@ -250,16 +266,54 @@
  * mostly used to synchronize between system wide and per-process
  */
 typedef struct {
-	spinlock_t		pfs_lock;		/* lock the structure */
+	spinlock_t		pfs_lock;		   /* lock the structure */
 
-	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 */
+	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;
 
 /*
+ * information about a PMC or PMD.
+ * dep_pmd[]: a bitmask of dependent PMD registers 
+ * dep_pmc[]: a bitmask of dependent PMC registers
+ */
+typedef struct {
+	pfm_pmu_reg_type_t	type;
+	int			pm_pos;
+	int			(*read_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+	int			(*write_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+	unsigned long		dep_pmd[4];
+	unsigned long		dep_pmc[4];
+} pfm_reg_desc_t;
+/* assume cnum is a valid monitor */
+#define PMC_PM(cnum, val)	(((val) >> (pmu_conf.pmc_desc[cnum].pm_pos)) & 0x1)
+#define PMC_WR_FUNC(cnum)	(pmu_conf.pmc_desc[cnum].write_check)
+#define PMD_WR_FUNC(cnum)	(pmu_conf.pmd_desc[cnum].write_check)
+#define PMD_RD_FUNC(cnum)	(pmu_conf.pmd_desc[cnum].read_check)
+
+/*
+ * This structure is initialized at boot time and contains
+ * a description of the PMU main characteristic as indicated
+ * by PAL along with a list of inter-registers dependencies and configurations.
+ */
+typedef struct {
+	unsigned long pfm_is_disabled;	/* indicates if perfmon is working properly */
+	unsigned long perf_ovfl_val;	/* overflow value for generic counters   */
+	unsigned long max_counters;	/* upper limit on counter pair (PMC/PMD) */
+	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 */
+	pfm_reg_desc_t *pmc_desc;	/* detailed PMC register descriptions */
+	pfm_reg_desc_t *pmd_desc;	/* detailed PMD register descriptions */
+} pmu_config_t;
+
+
+/*
  * structure used to pass argument to/from remote CPU 
  * using IPI to check and possibly save the PMU context on SMP systems.
  *
@@ -301,22 +355,50 @@
 #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)
 
+typedef struct {
+	int	debug;		/* turn on/off debugging via syslog */
+	int	debug_ovfl;	/* turn on/off debug printk in overflow handler */
+	int	fastctxsw;	/* turn on/off fast (unsecure) ctxsw */
+} pfm_sysctl_t;
+
+typedef struct {
+	unsigned long pfm_spurious_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
+	unsigned long pfm_ovfl_intr_count; /* keep track of ovfl interrupts */
+	unsigned long pfm_recorded_samples_count;
+	unsigned long pfm_full_smpl_buffer_count; /* how many times the sampling buffer was full */
+} pfm_stats_t;
 
 /*
  * perfmon internal variables
  */
 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;
+static pfm_stats_t	pfm_stats;
 
+/* sysctl() controls */
+static pfm_sysctl_t pfm_sysctl;
+
+static ctl_table pfm_ctl_table[]={
+	{1, "debug", &pfm_sysctl.debug, sizeof(int), 0666, NULL, &proc_dointvec, NULL,},
+	{2, "debug_ovfl", &pfm_sysctl.debug_ovfl, sizeof(int), 0666, NULL, &proc_dointvec, NULL,},
+	{3, "fastctxsw", &pfm_sysctl.fastctxsw, sizeof(int), 0600, NULL, &proc_dointvec, NULL,},
+	{ 0, },
+};
+static ctl_table pfm_sysctl_dir[] = {
+	{1, "perfmon", NULL, 0, 0755, pfm_ctl_table, },
+ 	{0,},
+};
+static ctl_table pfm_sysctl_root[] = {
+	{1, "kernel", NULL, 0, 0755, pfm_sysctl_dir, },
+ 	{0,},
+};
+static struct ctl_table_header *pfm_sysctl_header;
 
 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
 };
@@ -339,6 +421,14 @@
 #endif
 static void pfm_lazy_save_regs (struct task_struct *ta);
 
+#if   defined(CONFIG_ITANIUM)
+#include "perfmon_itanium.h"
+#elif defined(CONFIG_MCKINLEY)
+#include "perfmon_mckinley.h"
+#else
+#include "perfmon_generic.h"
+#endif
+
 static inline unsigned long
 pfm_read_soft_counter(pfm_context_t *ctx, int i)
 {
@@ -353,7 +443,7 @@
 	 * writing to unimplemented part is ignore, so we do not need to
 	 * mask off top part
 	 */
-	ia64_set_pmd(i, val);
+	ia64_set_pmd(i, val & pmu_conf.perf_ovfl_val);
 }
 
 /*
@@ -424,7 +514,6 @@
 	return pa;
 }
 
-
 static void *
 pfm_rvmalloc(unsigned long size)
 {
@@ -500,7 +589,7 @@
 	 *
 	 * 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
+	 * we have created our own with the linked list of sampling buffers to free. The list
 	 * 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
@@ -516,16 +605,15 @@
 		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(("[%d] add smpl @%p size %lu to smpl_buf_list psb_flags=0x%x\n", 
+			current->pid, psb->psb_hdr, psb->psb_size, psb->psb_flags));
 	}
-	DBprintk(("psb vma flag cleared for [%d] smpl @%p size %ld inserted into list\n", 
-			current->pid, psb->psb_hdr, psb->psb_size));
-
+	DBprintk(("[%d] clearing psb_flags=0x%x smpl @%p size %lu\n", 
+			current->pid, psb->psb_flags, psb->psb_hdr, psb->psb_size));
 	/*
-	 * indicate to pfm_context_exit() that the vma has been removed. 
+	 * decrement the number vma for the buffer
 	 */
-	psb->psb_flags &= ~PFM_PSB_VMA;
+	psb->psb_flags &= ~PSB_HAS_VMA;
 
 	UNLOCK_PSB(psb);
 }
@@ -548,7 +636,7 @@
 		printk("perfmon: invalid context mm=%p\n", task->mm);
 		return -1;
 	}
-	psb = ctx->ctx_psb;	
+	psb = ctx->ctx_psb;
 
 	down_write(&task->mm->mmap_sem);
 
@@ -559,14 +647,9 @@
 		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;
+	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", 
+		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags));
 
 	return 0;
 }
@@ -599,7 +682,7 @@
 	while (size > 0) {
 		page = pfm_kvirt_to_pa(buf);
 
-		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_SHARED)) return -ENOMEM;
+		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
 		
 		addr  += PAGE_SIZE;
 		buf   += PAGE_SIZE;
@@ -638,17 +721,25 @@
 	void *smpl_buf;
 	pfm_smpl_buffer_desc_t *psb;
 
-	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.
 	 */
+	regcount = pfm_smpl_entry_size(which_pmds, 1);
+
+	if ((sizeof(perfmon_smpl_hdr_t)+ entries*sizeof(perfmon_smpl_entry_t)) <= entries) {
+		DBprintk(("requested entries %lu is too big\n", entries));
+		return -EINVAL;
+	}
 
 	/*
 	 * 1 buffer hdr and for each entry a header + regcount PMDs to save
 	 */
 	size = PAGE_ALIGN(  sizeof(perfmon_smpl_hdr_t)
 			  + entries * (sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64)));
+
+	DBprintk(("sampling buffer size=%lu bytes\n", size));
+
 	/*
 	 * check requested size to avoid Denial-of-service attacks
 	 * XXX: may have to refine this test	
@@ -688,9 +779,13 @@
 	}
 	/*
 	 * partially initialize the vma for the sampling buffer
+	 *
+	 * The VM_DONTCOPY flag is very important as it ensures that the mapping
+	 * will never be inherited for any child process (via fork()) which is always 
+	 * what we want.
 	 */
 	vma->vm_mm	     = mm;
-	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED;
+	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED|VM_DONTCOPY;
 	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;
@@ -708,8 +803,8 @@
 	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;
+	psb->psb_flags   = PSB_HAS_VMA;
 
 	spin_lock_init(&psb->psb_lock);
 
@@ -719,9 +814,9 @@
 	 */
 	psb->psb_entry_size = sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64);
 
-	DBprintk(("psb @%p entry_size=%ld hdr=%p addr=%p\n", 
+	DBprintk(("psb @%p entry_size=%ld hdr=%p addr=%p refcnt=%lu psb_flags=0x%x\n", 
 		  (void *)psb,psb->psb_entry_size, (void *)psb->psb_hdr, 
-		  (void *)psb->psb_addr));
+		  (void *)psb->psb_addr, psb->psb_refcnt, psb->psb_flags));
 
 	/* initialize some of the fields of user visible buffer header */
 	psb->psb_hdr->hdr_version    = PFM_SMPL_VERSION;
@@ -797,7 +892,6 @@
 	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
 }
 
-
 static int
 pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
 {
@@ -813,6 +907,11 @@
 	}
 	ctx_flags = pfx->ctx_flags;
 
+	if ((ctx_flags & PFM_FL_INHERIT_MASK) == (PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)) {
+		DBprintk(("invalid inherit mask 0x%x\n",ctx_flags & PFM_FL_INHERIT_MASK));
+		return -EINVAL;
+	}
+
 	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
 		DBprintk(("cpu_mask=0x%lx\n", pfx->ctx_cpu_mask));
 		/*
@@ -832,8 +931,8 @@
 		/*
 		 * and it must be a valid CPU
 		 */
-		cpu = ffs(pfx->ctx_cpu_mask);
-		if (cpu > smp_num_cpus) {
+		cpu = ffz(~pfx->ctx_cpu_mask);
+		if (cpu_is_online(cpu) == 0) {
 			DBprintk(("CPU%d is not online\n", cpu));
 			return -EINVAL;
 		}
@@ -851,7 +950,16 @@
 		 * 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;
+		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == 0) {
+			DBprintk(("must have notify_pid when blocking for [%d]\n", task->pid));
+			return -EINVAL;
+		}
+#if 0
+		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == task->pid) {
+			DBprintk(("cannot notify self when blocking for [%d]\n", task->pid));
+			return -EINVAL;
+		}
+#endif
 	}
 	/* probably more to add here */
 
@@ -859,7 +967,7 @@
 }
 
 static int
-pfm_create_context(struct task_struct *task, pfm_context_t *ctx, void *req, int count, 
+pfm_context_create(struct task_struct *task, pfm_context_t *ctx, void *req, int count, 
 		   struct pt_regs *regs)
 {
 	pfarg_context_t tmp;
@@ -890,7 +998,7 @@
 	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;
+		cpu = ffz(~tmp.ctx_cpu_mask);
 
 		DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id()));
 
@@ -984,7 +1092,7 @@
 	}
 
 	if (tmp.ctx_smpl_entries) {
-		DBprintk(("sampling entries=%ld\n",tmp.ctx_smpl_entries));
+		DBprintk(("sampling entries=%lu\n",tmp.ctx_smpl_entries));
 
 		ret = pfm_smpl_buffer_alloc(ctx, tmp.ctx_smpl_regs, 
 						 tmp.ctx_smpl_entries, &uaddr);
@@ -1010,20 +1118,12 @@
 
 	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.ctx_smpl_regs[0] & pmu_conf.impl_regs[4];
-	ctx->ctx_saved_pmcs[0] = 1; /* always save/restore PMC[0] */
+	/* may be redudant with memset() but at least it's easier to remember */
+	atomic_set(&ctx->ctx_saving_in_progress, 0); 
+	atomic_set(&ctx->ctx_is_busy, 0); 
 
 	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
 
-
 	if (copy_to_user(req, &tmp, sizeof(tmp))) {
 		ret = -EFAULT;
 		goto buffer_error;
@@ -1126,21 +1226,22 @@
 			  	current->pid, 
 				flag == PFM_RELOAD_LONG_RESET ? "long" : "short", i, val));
 	}
+	ia64_srlz_d();
 	/* just in case ! */
 	ctx->ctx_ovfl_regs[0] = 0UL;
 }
 
 static int
-pfm_write_pmcs(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_write_pmcs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &ta->thread;
+	struct thread_struct *th = &task->thread;
 	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 (task != current) return -EINVAL;
 
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
@@ -1169,30 +1270,30 @@
 		 * 	- per-task : user monitor
 		 * any other configuration is rejected.
 		 */
-		if (PMC_IS_MONITOR(cnum)) {
-			pfm_monitor_t *p = (pfm_monitor_t *)&tmp.reg_value;
-
-			DBprintk(("pmc[%u].pm = %d\n", cnum, p->pmc_pm));
+		if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
+			DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, tmp.reg_value))); 
 
-			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)) {
+			if (ctx->ctx_fl_system ^ PMC_PM(cnum, tmp.reg_value)) {
+				DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, tmp.reg_value), ctx->ctx_fl_system));
 				ret = -EINVAL;
 				goto abort_mission;
 			}
-			/*
-			 * enforce generation of overflow interrupt. Necessary on all
-			 * CPUs which do not implement 64-bit hardware counters.
-			 */
-			p->pmc_oi = 1;
 		}
 
 		if (PMC_IS_COUNTING(cnum)) {
+			pfm_monitor_t *p = (pfm_monitor_t *)&tmp.reg_value;
+			/*
+		 	 * enforce generation of overflow interrupt. Necessary on all
+		 	 * CPUs.
+		 	 */
+			p->pmc_oi = 1;
+
 			if (tmp.reg_flags & PFM_REGFL_OVFL_NOTIFY) {
 				/*
 				 * must have a target for the signal
 				 */
 				if (ctx->ctx_notify_task == NULL) {
+					DBprintk(("no notify_task && PFM_REGFL_OVFL_NOTIFY\n"));
 					ret = -EINVAL;
 					goto abort_mission;
 				}
@@ -1206,14 +1307,11 @@
 			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);
 		}
+		/*
+		 * execute write checker, if any
+		 */
+		if (PMC_WR_FUNC(cnum)) ret = PMC_WR_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
 abort_mission:
 		if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
 
@@ -1233,14 +1331,21 @@
 		 */
 		if (ret != 0) {
 			DBprintk(("[%d] pmc[%u]=0x%lx error %d\n",
-				  ta->pid, cnum, tmp.reg_value, reg_retval));
+				  task->pid, cnum, tmp.reg_value, reg_retval));
 			break;
 		}
 
 		/* 
 		 * We can proceed with this register!
 		 */
-		
+
+		/*
+		 * 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, pmu_conf.pmc_desc[cnum].dep_pmd[0]);
+
 		/* 
 		 * keep copy the pmc, used for register reload
 		 */
@@ -1248,17 +1353,17 @@
 
 		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, 
+		DBprintk(("[%d] pmc[%u]=0x%lx flags=0x%x used_pmds=0x%lx\n", 
+			  task->pid, cnum, tmp.reg_value, 
 			  ctx->ctx_soft_pmds[cnum].flags, 
-			  ctx->ctx_saved_pmcs[0], ctx->ctx_reload_pmcs[0]));
+			  ctx->ctx_used_pmds[0]));
 
 	}
 	return ret;
 }
 
 static int
-pfm_write_pmds(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
 	unsigned int cnum;
@@ -1266,7 +1371,7 @@
 	int ret = 0, reg_retval = 0;
 
 	/* we don't quite support this right now */
-	if (ta != current) return -EINVAL;
+	if (task != current) return -EINVAL;
 
 	/* 
 	 * Cannot do anything before PMU is enabled 
@@ -1281,7 +1386,6 @@
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
 		cnum = tmp.reg_num;
-
 		if (!PMD_IS_IMPL(cnum)) {
 			ret = -EINVAL;
 			goto abort_mission;
@@ -1295,6 +1399,10 @@
 			ctx->ctx_soft_pmds[cnum].short_reset = tmp.reg_short_reset;
 
 		}
+		/*
+		 * execute write checker, if any
+		 */
+		if (PMD_WR_FUNC(cnum)) ret = PMD_WR_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
 abort_mission:
 		if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
 
@@ -1311,21 +1419,24 @@
 		 */
 		if (ret != 0) {
 			DBprintk(("[%d] pmc[%u]=0x%lx error %d\n",
-				  ta->pid, cnum, tmp.reg_value, reg_retval));
+				  task->pid, cnum, tmp.reg_value, reg_retval));
 			break;
 		}
 
 		/* keep track of what we use */
-		CTX_USED_PMD(ctx, cnum);
+		CTX_USED_PMD(ctx, pmu_conf.pmd_desc[(cnum)].dep_pmd[0]);
+		/* mark this register as used as well */
+		CTX_USED_PMD(ctx, RDEP(cnum));
 
 		/* writes to unimplemented part is ignored, so this is safe */
-		ia64_set_pmd(cnum, tmp.reg_value);
+		ia64_set_pmd(cnum, tmp.reg_value & pmu_conf.perf_ovfl_val);
 
 		/* to go away */
 		ia64_srlz_d();
+
 		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,
+				task->pid, cnum,
 				ctx->ctx_soft_pmds[cnum].val,
 				ctx->ctx_soft_pmds[cnum].short_reset,
 				ctx->ctx_soft_pmds[cnum].long_reset,
@@ -1338,12 +1449,13 @@
 }
 
 static int
-pfm_read_pmds(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &ta->thread;
+	struct thread_struct *th = &task->thread;
 	unsigned long val=0;
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
-	int i;
+	unsigned int cnum;
+	int i, ret = 0;
 
 	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
@@ -1356,14 +1468,25 @@
 
 	/* XXX: ctx locking may be required here */
 
-	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), ta->pid));
+	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
 
 	for (i = 0; i < count; i++, req++) {
-		unsigned long reg_val = ~0UL, ctx_val = ~0UL;
+		unsigned long ctx_val = ~0UL;
 
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-		if (!PMD_IS_IMPL(tmp.reg_num)) goto abort_mission;
+		cnum = tmp.reg_num;
+
+		if (!PMD_IS_IMPL(cnum)) goto abort_mission;
+		/*
+		 * we can only read the register that we use. That includes
+		 * the one we explicitely initialize AND the one we want included
+		 * in the sampling buffer (smpl_regs).
+		 *
+		 * Having this restriction allows optimization in the ctxsw routine
+		 * without compromising security (leaks)
+		 */
+		if (!CTX_IS_USED_PMD(ctx, cnum)) goto abort_mission;
 
 		/*
 		 * If the task is not the current one, then we check if the
@@ -1372,8 +1495,8 @@
 		 */
 		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));
+			val = ia64_get_pmd(cnum);
+			DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
 		} else {
 #ifdef CONFIG_SMP
 			int cpu;
@@ -1389,30 +1512,35 @@
 			 */
 			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);
+				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid));
+				pfm_fetch_regs(cpu, task, ctx);
 			}
 #endif
 			/* context has been saved */
-			val = reg_val = th->pmd[tmp.reg_num];
+			val = th->pmd[cnum];
 		}
-		if (PMD_IS_COUNTING(tmp.reg_num)) {
+		if (PMD_IS_COUNTING(cnum)) {
 			/*
 			 * XXX: need to check for overflow
 			 */
 
 			val &= pmu_conf.perf_ovfl_val;
-			val += ctx_val = ctx->ctx_soft_pmds[tmp.reg_num].val;
-		} else {
+			val += ctx_val = ctx->ctx_soft_pmds[cnum].val;
+		} 
 
-			val = reg_val = ia64_get_pmd(tmp.reg_num);
-		}
-		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
 		tmp.reg_value = val;
 
-		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)));
+		/*
+		 * execute read checker, if any
+		 */
+		if (PMD_RD_FUNC(cnum)) {
+			ret = PMD_RD_FUNC(cnum)(task, cnum, &tmp.reg_value, regs);
+		}
+
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, ret);
+
+		DBprintk(("read pmd[%u] ret=%d value=0x%lx pmc=0x%lx\n", 
+					cnum, ret, val, ia64_get_pmc(cnum)));
 
 		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
 	}
@@ -1420,7 +1548,7 @@
 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!
+	 * XXX: if this fails, we stick with the original failure, flag not updated!
 	 */
 	copy_to_user(req, &tmp, sizeof(tmp));
 	return -EINVAL;
@@ -1455,15 +1583,11 @@
 	 */
 	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 
+	 * We cannot allow setting breakpoints when system wide monitoring
+	 * sessions are using the debug registers.
 	 */
 	if (pfm_sessions.pfs_sys_use_dbregs> 0)
 		ret = -1;
@@ -1516,6 +1640,7 @@
 {
 	return 0;
 }
+
 int
 pfm_release_debug_registers(struct task_struct *task)
 {
@@ -1534,12 +1659,6 @@
 	 */
 	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));
 
@@ -1656,25 +1775,35 @@
 				current->pid,
 				ctx->ctx_fl_system, PMU_OWNER(),
 				current));
+
 	/* simply stop monitoring but not the PMU */
 	if (ctx->ctx_fl_system) {
 
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
-
 		/* disable dcr pp */
 		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
+		/* stop monitoring */
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+
+		ia64_srlz_i();
+
 #ifdef CONFIG_SMP
 		local_cpu_data->pfm_dcr_pp  = 0;
 #else
 		pfm_tasklist_toggle_pp(0);
 #endif
-
 		ia64_psr(regs)->pp = 0;
 
 	} else {
+
+		/* stop monitoring */
 		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
 
+		ia64_srlz_i();
+
+		/*
+		 * clear user level psr.up
+		 */
 		ia64_psr(regs)->up = 0;
 	}
 	return 0;
@@ -1701,7 +1830,7 @@
 		ia64_psr(regs)->up = 0;
 	}
 	/* 
-	 * goes back to default behavior 
+	 * goes back to default behavior: no user level control
 	 * no need to change live psr.sp because useless at the kernel level
 	 */
 	ia64_psr(regs)->sp = 1;
@@ -1713,10 +1842,8 @@
 	return 0;
 }
 
-
-
 static int
-pfm_destroy_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+pfm_context_destroy(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
 	 struct pt_regs *regs)
 {
 	/* we don't quite support this right now */
@@ -1742,15 +1869,14 @@
 		ia64_psr(regs)->up = 0;
 	}
 
-	/* restore security level */
-	ia64_psr(regs)->sp = 1;
-
 skipped_stop:
 	/*
 	 * remove sampling buffer mapping, if any
 	 */
-	if (ctx->ctx_smpl_vaddr) pfm_remove_smpl_mapping(task);
-
+	if (ctx->ctx_smpl_vaddr) {
+		pfm_remove_smpl_mapping(task);
+		ctx->ctx_smpl_vaddr = 0UL;
+	}
 	/* now free context and related state */
 	pfm_context_exit(task);
 
@@ -1761,7 +1887,7 @@
  * does nothing at the moment
  */
 static int
-pfm_unprotect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+pfm_context_unprotect(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
 	 struct pt_regs *regs)
 {
 	return 0;
@@ -1791,9 +1917,9 @@
 {
 	unsigned int mode = *(unsigned int *)arg;
 
-	pfm_debug_mode = mode == 0 ? 0 : 1;
+	pfm_sysctl.debug = mode == 0 ? 0 : 1;
 
-	printk("perfmon debugging %s\n", pfm_debug_mode ? "on" : "off");
+	printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
 
 	return 0;
 }
@@ -1863,8 +1989,8 @@
 	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) {
+		DBprintk(("system-wide setting fl_using_dbreg for [%d]\n", task->pid));
+	} else if (first_time) {
 			ret= -EBUSY;
 			if ((thread->flags & IA64_THREAD_DBG_VALID) != 0) {
 				DBprintk(("debug registers already in use for [%d]\n", task->pid));
@@ -1873,6 +1999,7 @@
 			/* we mark ourselves as owner  of the debug registers */
 			ctx->ctx_fl_using_dbreg = 1;
 
+			DBprintk(("setting fl_using_dbreg for [%d]\n", task->pid));
 			/* 
 			 * Given debug registers cannot be used for both debugging 
 			 * and performance monitoring at the same time, we reuse
@@ -1880,18 +2007,27 @@
 			 */
 			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);
-			}
-			for (i=0; i < pmu_conf.num_dbrs; i++) {
-				ia64_set_dbr(i, 0UL);
-			}
+	if (first_time) {
+		DBprintk(("[%d] clearing ibrs,dbrs\n", task->pid));
+		/*
+	 	 * clear hardware registers to make sure we don't
+	 	 * pick up stale state. 
+		 *
+		 * for a system wide session, we do not use
+		 * thread.dbr, thread.ibr because this process
+		 * never leaves the current CPU and the state
+		 * is shared by all processes running on it
+	 	 */
+		for (i=0; i < pmu_conf.num_ibrs; i++) {
+			ia64_set_ibr(i, 0UL);
+		}
+		ia64_srlz_i();
+		for (i=0; i < pmu_conf.num_dbrs; i++) {
+			ia64_set_dbr(i, 0UL);
 		}
+		ia64_srlz_d();
 	}
 
 	ret = -EFAULT;
@@ -1951,6 +2087,7 @@
 			CTX_USED_IBR(ctx, rnum);
 
 			ia64_set_ibr(rnum, dbreg.val);
+			ia64_srlz_i();
 
 			thread->ibr[rnum] = dbreg.val;
 
@@ -1959,6 +2096,7 @@
 			CTX_USED_DBR(ctx, rnum);
 
 			ia64_set_dbr(rnum, dbreg.val);
+			ia64_srlz_d();
 
 			thread->dbr[rnum] = dbreg.val;
 
@@ -2058,27 +2196,35 @@
 
 	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
+		/* set user level psr.pp */
 		ia64_psr(regs)->pp = 1;
 
+		/* start monitoring at kernel level */
 		__asm__ __volatile__ ("ssm psr.pp;;"::: "memory");
 
+		/* enable dcr pp */
+		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
+
+		ia64_srlz_i();
+
 	} 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;
 		}
+		/* set user level psr.up */
 		ia64_psr(regs)->up = 1;
+
+		/* start monitoring at kernel level */
 		__asm__ __volatile__ ("sum psr.up;;"::: "memory");
+
+		ia64_srlz_i();
 	}
-	ia64_srlz_d();
 
 	return 0;
 }
@@ -2101,7 +2247,9 @@
 		ia64_psr(regs)->pp = 0;
 		ia64_psr(regs)->up = 0; /* just to make sure! */
 
+		/* make sure monitoring is stopped */
 		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+		ia64_srlz_i();
 
 #ifdef CONFIG_SMP
 		local_cpu_data->pfm_syst_wide = 1;
@@ -2116,21 +2264,21 @@
 		ia64_psr(regs)->pp = 0; /* just to make sure! */
 		ia64_psr(regs)->up = 0;
 
+		/* make sure monitoring is stopped */
 		__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;
-		}
+		ia64_srlz_i();
+
+		DBprintk(("clearing psr.sp for [%d]\n", current->pid));
+
+		/* allow user level control  */
+		ia64_psr(regs)->sp = 0;
+
+		/* PMU state will be saved/restored on ctxsw */
 		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());
 
@@ -2141,6 +2289,40 @@
 	return 0;
 }
 
+static int
+pfm_get_pmc_reset(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	   struct pt_regs *regs)
+{
+	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
+	unsigned int cnum;
+	int i;
+
+	for (i = 0; i < count; i++, req++) {
+
+		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
+
+		cnum = tmp.reg_num;
+
+		if (!PMC_IS_IMPL(cnum)) goto abort_mission;
+
+		tmp.reg_value = reset_pmcs[cnum];
+
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
+
+		DBprintk(("pmc_reset_val pmc[%u]=0x%lx\n", cnum, tmp.reg_value)); 
+
+		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 with the original failure, flag not updated!
+	 */
+	copy_to_user(req, &tmp, sizeof(tmp));
+	return -EINVAL;
+}
+
 /*
  * functions MUST be listed in the increasing order of their index (see permfon.h)
  */
@@ -2148,19 +2330,19 @@
 /* 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)},
+/* 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},
+/* 8  */{ pfm_context_create, PFM_CMD_PID|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, 1, sizeof(pfarg_context_t)},
+/* 9  */{ pfm_context_destroy, 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 */
+/* 14 */{ pfm_context_unprotect, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 15 */{ pfm_get_pmc_reset, PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
 /* 16 */{ NULL, 0, 0, 0}, /* not used */
 /* 17 */{ NULL, 0, 0, 0}, /* not used */
 /* 18 */{ NULL, 0, 0, 0}, /* not used */
@@ -2222,9 +2404,9 @@
 {
 	struct pt_regs *regs = (struct pt_regs *)&stack;
 	struct task_struct *task = current;
-	pfm_context_t *ctx = task->thread.pfm_context;
+	pfm_context_t *ctx;
 	size_t sz;
-	int ret = -ESRCH, narg;
+	int ret, narg;
 
 	/* 
 	 * reject any call if perfmon was disabled at initialization time
@@ -2254,6 +2436,8 @@
 
 		if (pid != current->pid) {
 
+			ret = -ESRCH;
+
 			read_lock(&tasklist_lock);
 
 			task = find_task_by_pid(pid);
@@ -2268,10 +2452,11 @@
 				ret = check_task_state(task);
 				if (ret != 0) goto abort_call;
 			}
-			ctx = task->thread.pfm_context;
-		}
+		} 
 	} 
 
+	ctx = task->thread.pfm_context;
+
 	if (PFM_CMD_USE_CTX(cmd)) {
 		ret = -EINVAL;
 	       if (ctx == NULL) {
@@ -2387,9 +2572,9 @@
 	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));
+	DBprintk_ovfl(("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
@@ -2409,7 +2594,7 @@
 	/*
 	 * initialize entry header
 	 */
-	h->pid  = task->pid;
+	h->pid  = current->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 */
@@ -2437,24 +2622,27 @@
 		} else {
 			*e = ia64_get_pmd(j); /* slow */
 		}
-		DBprintk(("e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
+		DBprintk_ovfl(("e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
 		e++;
 	}
+	pfm_stats.pfm_recorded_samples_count++;
+
 	/*
 	 * 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", 
+	DBprintk_ovfl(("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"));
+		DBprintk_ovfl(("sampling buffer full\n"));
 		/*
 		 * XXX: must reset buffer in blocking mode and lost notified
 		 */
+		pfm_stats.pfm_full_smpl_buffer_count++;
 		return 1;
 	}
 	return 0;
@@ -2467,15 +2655,13 @@
  *	new value of pmc[0]. if 0x0 then unfreeze, else keep frozen
  */
 static unsigned long
-pfm_overflow_handler(struct task_struct *task, u64 pmc0, struct pt_regs *regs)
+pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
 {
 	unsigned long mask;
 	struct thread_struct *t;
-	pfm_context_t *ctx;
 	unsigned long old_val;
 	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
 	int i;
-	int my_cpu = smp_processor_id();
 	int ret = 1;
 	struct siginfo si;
 	/*
@@ -2491,18 +2677,7 @@
 	 * valid one, i.e. the one that caused the interrupt.
 	 */
 
-	if (task == NULL) {
-		DBprintk(("owners[%d]=NULL\n", my_cpu));
-		return 0x1;
-	}
 	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
@@ -2524,12 +2699,12 @@
 
 	mask = pmc0 >> PMU_FIRST_COUNTER;
 
-	DBprintk(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
-		  " mode used_pmds=0x%lx save_pmcs=0x%lx reload_pmcs=0x%lx\n", 
+	DBprintk_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
+		  " mode used_pmds=0x%lx used_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_used_pmcs[0],
 			ctx->ctx_reload_pmcs[0]));
 
 	/*
@@ -2540,7 +2715,7 @@
 		/* skip pmd which did not overflow */
 		if ((mask & 0x1) == 0) continue;
 
-		DBprintk(("PMD[%d] overflowed hw_pmd=0x%lx soft_pmd=0x%lx\n", 
+		DBprintk_ovfl(("pmd[%d] overflowed hw_pmd=0x%lx soft_pmd=0x%lx\n", 
 			  i, ia64_get_pmd(i), ctx->ctx_soft_pmds[i].val));
 
 		/*
@@ -2552,8 +2727,7 @@
 		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);
 
-
-		DBprintk(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx\n", 
+		DBprintk_ovfl(("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));
 
@@ -2570,7 +2744,7 @@
 
 			ovfl_pmds |= 1UL << i;
 
-			DBprintk(("soft_pmd[%d] overflowed flags=0x%x, ovfl=0x%lx\n", i, ctx->ctx_soft_pmds[i].flags, ovfl_pmds));
+			DBprintk_ovfl(("soft_pmd[%d] overflowed flags=0x%x, ovfl=0x%lx\n", i, ctx->ctx_soft_pmds[i].flags, ovfl_pmds));
 
 			if (PMC_OVFL_NOTIFY(ctx, i)) {
 				ovfl_notify |= 1UL << i;
@@ -2609,7 +2783,8 @@
 	 * No overflow requiring a user level notification
 	 */
 	if (ovfl_notify == 0UL) {
-		pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET);
+		if (ovfl_pmds) 
+			pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET);
 		return 0x0;
 	}
 
@@ -2684,7 +2859,7 @@
 	 	 * necessarily go to the signal handler (if any) when it goes back to
 	 	 * user mode.
 	 	 */
-		DBprintk(("[%d] sending notification to [%d]\n", 
+		DBprintk_ovfl(("[%d] sending notification to [%d]\n", 
 			  task->pid, ctx->ctx_notify_task->pid));
 
 
@@ -2717,7 +2892,7 @@
 		 * before, changing it to NULL will still maintain this invariant.
 		 * Of course, when it is equal to current it cannot change at this point.
 		 */
-		DBprintk(("block=%d notify [%d] current [%d]\n", 
+		DBprintk_ovfl(("block=%d notify [%d] current [%d]\n", 
 			ctx->ctx_fl_block,
 			ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, 
 			current->pid ));
@@ -2728,7 +2903,7 @@
 	} else {
 lost_notify: /* XXX: more to do here, to convert to non-blocking (reset values) */
 
-		DBprintk(("notification task has disappeared !\n"));
+		DBprintk_ovfl(("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 
@@ -2750,7 +2925,7 @@
 	 */
 	ctx->ctx_fl_frozen = 1;
 
-	DBprintk(("reload pmc0=0x%x must_block=%ld\n",
+	DBprintk_ovfl(("return 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;
@@ -2761,8 +2936,9 @@
 {
 	u64 pmc0;
 	struct task_struct *task;
+	pfm_context_t *ctx;
 
-	pfm_ovfl_intr_count++;
+	pfm_stats.pfm_ovfl_intr_count++;
 
 	/* 
 	 * srlz.d done before arriving here
@@ -2776,24 +2952,54 @@
 	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
 	 */
 	if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) {
-
 		/* 
-		 * assumes, PMC[0].fr = 1 at this point 
-		 *
-		 * XXX: change protype to pass &pmc0
+		 * we assume that pmc0.fr is always set here
 		 */
-		pmc0 = pfm_overflow_handler(task, pmc0, regs);
+		ctx = task->thread.pfm_context;
 
-		/* we never explicitely freeze PMU here */
-		if (pmc0 == 0) {
-			ia64_set_pmc(0, 0);
-			ia64_srlz_d();
+		/* sanity check */
+		if (!ctx) {
+			printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
+				task->pid);
+			return;
 		}
+#ifdef CONFIG_SMP
+		/*
+		 * Because an IPI has higher priority than the PMU overflow interrupt, it is 
+		 * possible that the handler be interrupted by a request from another CPU to fetch 
+		 * the PMU state of the currently active context. The task may have just been 
+		 * migrated to another CPU which is trying to restore the context. If there was
+		 * a pending overflow interrupt when the task left this CPU, it is possible for
+		 * the handler to get interrupt by the IPI. In which case, we fetch request
+		 * MUST be postponed until the interrupt handler is done. The ctx_is_busy
+		 * flag indicates such a condition. The other CPU must busy wait until it's cleared.
+		 */
+		atomic_set(&ctx->ctx_is_busy, 1);
+#endif
+
+		/* 
+		 * assume PMC[0].fr = 1 at this point 
+		 */
+		pmc0 = pfm_overflow_handler(task, ctx, pmc0, regs);
+
+		/*
+		 * We always clear the overflow status bits and either unfreeze
+		 * or keep the PMU frozen.
+		 */
+		ia64_set_pmc(0, pmc0);
+		ia64_srlz_d();
+
+#ifdef CONFIG_SMP
+		/*
+		 * announce that we are doing with the context
+		 */
+		atomic_set(&ctx->ctx_is_busy, 0);
+#endif
 	} else {
-		pfm_spurious_ovfl_intr_count++;
+		pfm_stats.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()));
+		printk("perfmon: Spurious PMU overflow interrupt on CPU%d: pmc0=0x%lx owner=%p\n", 
+			smp_processor_id(), pmc0, (void *)PMU_OWNER());
 	}
 }
 
@@ -2801,33 +3007,31 @@
 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, "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");
+	p += sprintf(p, "enabled          : %s\n", pmu_conf.pfm_is_disabled ? "No": "Yes");
+	p += sprintf(p, "fastctxsw        : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No");
+	p += sprintf(p, "ovfl_mask        : 0x%lx\n", pmu_conf.perf_ovfl_val);
+	p += sprintf(p, "overflow intrs   : %lu\n", pfm_stats.pfm_ovfl_intr_count);
+	p += sprintf(p, "spurious intrs   : %lu\n", pfm_stats.pfm_spurious_ovfl_intr_count);
+	p += sprintf(p, "recorded samples : %lu\n", pfm_stats.pfm_recorded_samples_count);
+	p += sprintf(p, "smpl buffer full : %lu\n", pfm_stats.pfm_full_smpl_buffer_count);
 
 #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);
+	p += sprintf(p, "CPU%d syst_wide   : %d\n"
+			"CPU%d dcr_pp      : %d\n", 
+			smp_processor_id(), 
+			local_cpu_data->pfm_syst_wide, 
+			smp_processor_id(), 
+			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", 
+	p += sprintf(p, "proc_sessions    : %lu\n"
+			"sys_sessions     : %lu\n"
+			"sys_use_dbregs   : %lu\n"
+			"ptrace_use_dbregs: %lu\n", 
 			pfm_sessions.pfs_task_sessions, 
 			pfm_sessions.pfs_sys_sessions,
 			pfm_sessions.pfs_sys_use_dbregs,
@@ -2837,12 +3041,28 @@
 
 	for(i=0; i < NR_CPUS; i++) {
 		if (cpu_is_online(i)) {
-			p += sprintf(p, "CPU%d.pmu_owner: %-6d\n",
+			p += sprintf(p, "CPU%d owner : %-6d\n",
 					i, 
 					pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
 		}
 	}
 
+	for(i=0; pmd_desc[i].type != PFM_REG_NONE; i++) {
+		p += sprintf(p, "PMD%-2d: %d 0x%lx 0x%lx\n", 
+				i,
+				pmd_desc[i].type, 
+				pmd_desc[i].dep_pmd[0], 
+				pmd_desc[i].dep_pmc[0]); 
+	}
+
+	for(i=0; pmc_desc[i].type != PFM_REG_NONE; i++) {
+		p += sprintf(p, "PMC%-2d: %d 0x%lx 0x%lx\n", 
+				i, 
+				pmc_desc[i].type, 
+				pmc_desc[i].dep_pmd[0], 
+				pmc_desc[i].dep_pmc[0]); 
+	}
+
 	return p - page;
 }
 
@@ -2901,6 +3121,7 @@
 	 * It will be restored from ipsr when going back to user level
 	 */
 	__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+	ia64_srlz_i();
 
 	ctx->ctx_saved_psr = psr;
 
@@ -2956,13 +3177,9 @@
 	for (i=0; mask; i++, mask>>=1) {
 		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
 	}
-	/*
-	 * 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);
-	}
+
+	/* save pmc0 */
+	t->pmc[0] = ia64_get_pmc(0);
 
 	/* not owned by this CPU */
 	atomic_set(&ctx->ctx_last_cpu, -1);
@@ -3000,6 +3217,12 @@
 		  PMU_OWNER() ? PMU_OWNER()->pid: -1,
 		  atomic_read(&ctx->ctx_saving_in_progress)));
 
+	/* must wait until not busy before retrying whole request */
+	if (atomic_read(&ctx->ctx_is_busy)) {
+		arg->retval = 2;
+		return;
+	}
+
 	/* must wait if saving was interrupted */
 	if (atomic_read(&ctx->ctx_saving_in_progress)) {
 		arg->retval = 1;
@@ -3012,9 +3235,9 @@
 		return;
 	}
 
-	DBprintk(("saving state for [%d] save_pmcs=0x%lx all_pmcs=0x%lx used_pmds=0x%lx\n", 
+	DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", 
 		arg->task->pid,
-		ctx->ctx_saved_pmcs[0],
+		ctx->ctx_used_pmcs[0],
 		ctx->ctx_reload_pmcs[0],
 		ctx->ctx_used_pmds[0]));
 
@@ -3027,17 +3250,15 @@
 
 	/*
 	 * XXX needs further optimization.
-	 * Also must take holes into account
 	 */
 	mask = ctx->ctx_used_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
-	}
-	
-	mask = ctx->ctx_saved_pmcs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmc[i] = ia64_get_pmc(i);
+		if (mask & 0x1) t->pmd[i] = ia64_get_pmd(i);
 	}
+
+	/* save pmc0 */
+	t->pmc[0] = ia64_get_pmc(0);
+
 	/* not owned by this CPU */
 	atomic_set(&ctx->ctx_last_cpu, -1);
 
@@ -3066,11 +3287,17 @@
 	arg.task   = task;
 	arg.retval = -1;
 
+	if (atomic_read(&ctx->ctx_is_busy)) {
+must_wait_busy:
+		while (atomic_read(&ctx->ctx_is_busy));
+	}
+
 	if (atomic_read(&ctx->ctx_saving_in_progress)) {
 		DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
-
+must_wait_saving:
 		/* busy wait */
 		while (atomic_read(&ctx->ctx_saving_in_progress));
+		DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu));
 		return;
 	}
 	DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id()));
@@ -3090,11 +3317,8 @@
 	 * 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));
-	}
+	if (arg.retval == 1) goto must_wait_saving;
+	if (arg.retval == 2) goto must_wait_busy;
 }
 #endif /* CONFIG_SMP */
 
@@ -3113,6 +3337,30 @@
 
 	owner = PMU_OWNER();
 	ctx   = task->thread.pfm_context;
+	t     = &task->thread;
+
+	/*
+	 * we restore ALL the debug registers to avoid picking up 
+	 * stale state.
+	 *
+	 * This must be done even when the task is still the owner
+	 * as the registers may have been modified via ptrace()
+	 * (not perfmon) by the previous task. 
+	 *
+	 * XXX: dealing with this in a lazy fashion requires modifications
+	 * to the way the the debug registers are managed. This is will done
+	 * in the next version of perfmon.
+	 */
+	if (ctx->ctx_fl_using_dbreg) {
+		for (i=0; i < pmu_conf.num_ibrs; i++) {
+			ia64_set_ibr(i, t->ibr[i]);
+		}
+		ia64_srlz_i();
+		for (i=0; i < pmu_conf.num_dbrs; i++) {
+			ia64_set_dbr(i, t->dbr[i]);
+		}
+		ia64_srlz_d();
+	}
 
 	/*
 	 * if we were the last user, then nothing to do except restore psr
@@ -3148,55 +3396,37 @@
 		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
+	 * To avoid leaking information to the user level when psr.sp=0,
+	 * we must reload ALL implemented pmds (even the ones we don't use).
+	 * In the kernel we only allow PFM_READ_PMDS on registers which
+	 * we initialized or requested (sampling) so there is no risk there.
+	 *
+	 * As an optimization, we will only reload the PMD that we use when 
+	 * the context is in protected mode, i.e. psr.sp=1 because then there
+	 * is no leak possible.
 	 */
-	mask = ctx->ctx_used_pmds[0];
+	mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
 	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) 
-			ia64_set_pmd(i, t->pmd[i]);
-		else
-			ia64_set_pmd(i, 0UL);
+		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.perf_ovfl_val);
 	}
-	/* XXX: will need to clear all unused pmd, for security */
 
 	/* 
-	 * skip pmc[0] to avoid side-effects, 
-	 * all PMCs are systematically reloaded, unsued get default value
-	 * to avoid picking up stale configuration
+	 * PMC0 is never set in the mask because it is always restored
+	 * separately.  
+	 *
+	 * ALL PMCs are systematically reloaded, unused registers
+	 * get their default (PAL reset) values 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]);
-	}
-
-	/*
-	 * 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];
+	mask = ctx->ctx_reload_pmcs[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 (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
 	}
 
 	if (t->pmc[0] & ~0x1) {
-		ia64_srlz_d();
-		pfm_overflow_handler(task, t->pmc[0], NULL);
+		pfm_overflow_handler(task, ctx, t->pmc[0], NULL);
 	}
 
 	/*
@@ -3249,7 +3479,7 @@
 			 * 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.
+			 * initialize the entire set used in the context switch restore routine.
 	 		 */
 			t->pmc[i] = reset_pmcs[i];
 			DBprintk((" pmc[%d]=0x%lx\n", i, reset_pmcs[i]));
@@ -3258,39 +3488,61 @@
 	}
 	/*
 	 * clear reset values for PMD. 
-	 * XX: good up to 64 PMDS. Suppose that zero is a valid value.
+	 * XXX: 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);
+		t->pmd[i] = 0UL;
 	}
 
 	/*
-	 * On context switched restore, we must restore ALL pmc even
+	 * On context switched restore, we must restore ALL pmc and ALL pmd 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.
+	 * may otherwise pick up left over PMC, PMD 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.
+	 * same CPU but also on between 2 CPUs. 
+	 *
+	 * The problem with PMD is information leaking especially
+	 * to user level when psr.sp=0
 	 *
 	 * There is unfortunately no easy way to avoid this problem
-	 * on either UP or SMP. This definitively slows down the 
-	 * pfm_load_regs(). 
+	 * on either UP or SMP. This definitively slows down the
+	 * pfm_load_regs() function. 
 	 */
 	
 	 /*
 	  * 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
+	  * see any side effect of a stale state, such as opcode matching
 	  * or range restrictions, for instance.
+	  *
+	  * We never directly restore PMC0 so we do not include it in the mask.
 	  */
-	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0];
+	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0] & ~0x1;
+	/*
+	 * We must include all the PMD in this mask to avoid picking
+	 * up stale value and leak information, especially directly
+	 * at the user level when psr.sp=0
+	 */
+	ctx->ctx_reload_pmds[0] = pmu_conf.impl_regs[4];
+
+	/* 
+	 * 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] = ctx->ctx_smpl_regs[0] & pmu_conf.impl_regs[4];
+	ctx->ctx_used_pmcs[0] = 1; /* always save/restore PMC[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;
 
@@ -3312,7 +3564,7 @@
 {
 	pfm_context_t *ctx;
 	u64 pmc0;
-	unsigned long mask, mask2, val;
+	unsigned long mask2, val;
 	int i;
 
 	ctx = task->thread.pfm_context;
@@ -3334,22 +3586,28 @@
 	 */
 	if (ctx->ctx_fl_system) {
 
-		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
 
 		/* disable dcr pp */
 		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
+		/* stop monitoring */
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+
+		ia64_srlz_i();
+
 #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  {
 
+		/* stop monitoring */
 		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
 
+		ia64_srlz_i();
+
 		/* no more save/restore on ctxsw */
 		current->thread.flags &= ~IA64_THREAD_PM_VALID;
 	}
@@ -3383,7 +3641,7 @@
 	ia64_srlz_d();
 
 	/*
-	 * We don't need to restore psr, because we are on our way out anyway
+	 * We don't need to restore psr, because we are on our way out
 	 */
 
 	/*
@@ -3399,10 +3657,12 @@
 	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));
 
-	mask  = pmc0 >> PMU_FIRST_COUNTER;
-	mask2 = ctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
-
-	for (i = PMU_FIRST_COUNTER; mask2; i++, mask>>=1, mask2>>=1) {
+	/*
+	 * we save all the used pmds
+	 * we take care of overflows for pmds used as counters
+	 */
+	mask2 = ctx->ctx_used_pmds[0];
+	for (i = 0; mask2; i++, mask2>>=1) {
 
 		/* skip non used pmds */
 		if ((mask2 & 0x1) == 0) continue;
@@ -3410,7 +3670,6 @@
 		val = ia64_get_pmd(i);
 
 		if (PMD_IS_COUNTING(i)) {
-
 			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));
 
 			/* collect latest results */
@@ -3423,15 +3682,19 @@
 			 */
 			task->thread.pmd[i] = 0;
 
-			/* take care of overflow inline */
-			if (mask & 0x1) {
+			/* 
+			 * take care of overflow inline
+			 */
+			if (pmc0 & (1UL << i)) {
 				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 */
+			/* 
+			 * not a counter, just save value as is
+			 */
 			task->thread.pmd[i] = val;
 		}
 	}
@@ -3449,31 +3712,73 @@
 int
 pfm_inherit(struct task_struct *task, struct pt_regs *regs)
 {
-	pfm_context_t *ctx = current->thread.pfm_context;
+	pfm_context_t *ctx;
 	pfm_context_t *nctx;
-	struct thread_struct *th = &task->thread;
+	struct thread_struct *thread;
 	unsigned long m;
 	int i;
 
 	/*
+	 * the new task was copied from parent and therefore points
+	 * to the parent's context at this point
+	 */
+	ctx    = task->thread.pfm_context;
+	thread = &task->thread;
+
+	/*
 	 * make sure child cannot mess up the monitoring session
 	 */
 	 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);
+
+	/*
+	 * if there was a virtual mapping for the sampling buffer
+	 * the mapping is NOT inherited across fork() (see VM_DONTCOPY), 
+	 * so we don't have to explicitely remove it here. 
+	 *
+	 *
+	 * Part of the clearing of fields is also done in
+	 * copy_thread() because the fiels are outside the
+	 * pfm_context structure and can affect tasks not
+	 * using perfmon.
+	 */
+
+	/* clear pending notification */
+	task->thread.pfm_ovfl_block_reset = 0;
+
+	/*
+	 * clear cpu pinning restriction for child
+	 */
+	if (ctx->ctx_fl_system) {
+		task->cpus_allowed = ctx->ctx_saved_cpus_allowed;
+		task->need_resched = 1;
+
+	 	DBprintk(("setting cpus_allowed for [%d] to 0x%lx from 0x%lx\n", 
+			task->pid,
+			ctx->ctx_saved_cpus_allowed, 
+			current->cpus_allowed));
+	}
 
 	/*
 	 * takes care of easiest case first
 	 */
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_NONE) {
+
 		DBprintk(("removing PFM context for [%d]\n", task->pid));
-		task->thread.pfm_context     = NULL;
-		task->thread.pfm_ovfl_block_reset  = 0;
+
+		task->thread.pfm_context = NULL;
+
+		/* 
+		 * we must clear psr.up because the new child does
+		 * not have a context and the PM_VALID flag is cleared
+		 * in copy_thread().
+		 *
+		 * we do not clear psr.pp because it is always
+		 * controlled by the system wide logic and we should
+		 * never be here when system wide is running anyway
+		 */
+	 	ia64_psr(regs)->up = 0;
 
 		/* copy_thread() clears IA64_THREAD_PM_VALID */
 		return 0;
@@ -3487,69 +3792,82 @@
 
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) {
 		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
-		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);
+		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
+	}
+	/*
+	 * 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_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);
+	if (nctx->ctx_owner)
+		atomic_inc(&nctx->ctx_owner->thread.pfm_owners_check);
 
-		read_unlock(&tasklist_lock);
+	read_unlock(&tasklist_lock);
 
-		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
 
-		LOCK_PFS();
-		pfm_sessions.pfs_task_sessions++;
-		UNLOCK_PFS();
-	}
+	LOCK_PFS();
+	pfm_sessions.pfs_task_sessions++;
+	UNLOCK_PFS();
 
 	/* initialize counters in new context */
-	m = pmu_conf.counter_pmds[0] >> PMU_FIRST_COUNTER;
+	m = nctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
 	for(i = PMU_FIRST_COUNTER ; m ; m>>=1, i++) {
-		if (m & 0x1) {
+		if ((m & 0x1) && pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING) {
 			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;
+			thread->pmd[i]	      	   = nctx->ctx_soft_pmds[i].ival & pmu_conf.perf_ovfl_val;
 		}
+		/* what about the other pmds? zero or keep as is */
 
 	}
-	/* clear BTB index register */
-	th->pmd[16] = 0;
+	/*
+	 * clear BTB index register
+	 * XXX: CPU-model specific knowledge!
+	 */
+	thread->pmd[16] = 0;
 
-	/* if sampling then increment number of users of buffer */
-	if (nctx->ctx_psb) {
 
-		/*
-		 * XXX: nopt very pretty!
-		 */
+	nctx->ctx_fl_frozen    = 0;
+	nctx->ctx_ovfl_regs[0] = 0UL;
+	atomic_set(&nctx->ctx_last_cpu, -1);
+
+	/*
+	 * here nctx->ctx_psb == ctx->ctx_psb
+	 *
+	 * increment reference count to sampling
+	 * buffer, if any. Note that this is independent
+	 * from the virtual mapping. The latter is never
+	 * inherited while the former will be if context
+	 * is setup to something different from PFM_FL_INHERIT_NONE
+	 */
+	if (nctx->ctx_psb) {
 		LOCK_PSB(nctx->ctx_psb);
+
 		nctx->ctx_psb->psb_refcnt++;
+
+	 	DBprintk(("updated smpl @ %p refcnt=%lu psb_flags=0x%x\n", 
+			ctx->ctx_psb->psb_hdr,
+			ctx->ctx_psb->psb_refcnt,
+			ctx->ctx_psb->psb_flags));
+
 		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] = 0UL;
-
 	sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */
 
-	/* clear pending notification */
-	th->pfm_ovfl_block_reset = 0;
-
 	/* link with new task */
-	th->pfm_context    = nctx;
+	thread->pfm_context = nctx;
 
 	DBprintk(("nctx=%p for process [%d]\n", (void *)nctx, task->pid));
 
@@ -3559,7 +3877,7 @@
 	 */
 	if (current->thread.flags & IA64_THREAD_PM_VALID) {
 		DBprintk(("setting PM_VALID for [%d]\n", task->pid));
-		th->flags |= IA64_THREAD_PM_VALID;
+		thread->flags |= IA64_THREAD_PM_VALID;
 	}
 
 	return 0;
@@ -3588,9 +3906,9 @@
 
 		LOCK_PSB(psb);
 
-		DBprintk(("sampling buffer from [%d] @%p size %ld vma_flag=0x%x\n",
+		DBprintk(("sampling buffer from [%d] @%p size %ld refcnt=%lu psb_flags=0x%x\n",
 			task->pid,
-			psb->psb_hdr, psb->psb_size, psb->psb_flags));
+			psb->psb_hdr, psb->psb_size, psb->psb_refcnt, psb->psb_flags));
 
 		/*
 		 * in the case where we are the last user, we may be able to free
@@ -3613,7 +3931,7 @@
 			 *
 			 * See pfm_vm_close() and pfm_cleanup_smpl_buf() for more details.
 			 */
-			if ((psb->psb_flags & PFM_PSB_VMA) == 0) {
+			if ((psb->psb_flags & PSB_HAS_VMA) == 0) {
 
 				DBprintk(("cleaning sampling buffer from [%d] @%p size %ld\n",
 					task->pid,
@@ -3645,7 +3963,7 @@
 	 * 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 
+	 * during pfm_context_create(). 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 
@@ -3683,7 +4001,8 @@
 		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 */
+
+		/* update perfmon debug register usage 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);
@@ -3795,6 +4114,8 @@
 		}
 	}
 	read_unlock(&tasklist_lock);
+
+	atomic_set(&task->thread.pfm_owners_check, 0);
 }
 
 
@@ -3852,6 +4173,8 @@
 		}
 	}
 	read_unlock(&tasklist_lock);
+
+	atomic_set(&task->thread.pfm_notifiers_check, 0);
 }
 
 static struct irqaction perfmon_irqaction = {
@@ -3870,6 +4193,12 @@
 		if (i >= pmu_conf.num_pmcs) break;
 		if (PMC_IS_IMPL(i)) reset_pmcs[i] = ia64_get_pmc(i);
 	}
+#ifdef CONFIG_MCKINLEY
+	/*
+	 * set the 'stupid' enable bit to power the PMU!
+	 */
+	reset_pmcs[4] |= 1UL << 23;
+#endif
 }
 
 /*
@@ -3881,11 +4210,6 @@
 	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", 
@@ -3937,23 +4261,12 @@
 	 */
 	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
+	 * setup the register configuration descriptions for the CPU
 	 */
-	pmu_conf.counter_pmds[0] |= PMM(4)|PMM(5)|PMM(6)|PMM(7);
+	pmu_conf.pmc_desc = pmc_desc;
+	pmu_conf.pmd_desc = pmd_desc;
 
-#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;
 
@@ -3962,6 +4275,8 @@
 	 */
 	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
 
+	pfm_sysctl_header = register_sysctl_table(pfm_sysctl_root, 0);
+
 	spin_lock_init(&pfm_sessions.pfs_lock);
 
 	return 0;
@@ -3972,11 +4287,13 @@
 void
 perfmon_init_percpu (void)
 {
+	if (smp_processor_id() == 0)
+		register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
+
 	ia64_set_pmv(IA64_PERFMON_VECTOR);
 	ia64_srlz_d();
 }
 
-
 #else /* !CONFIG_PERFMON */
 
 asmlinkage int
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/perfmon_generic.h linux-2.4.20-pre7/arch/ia64/kernel/perfmon_generic.h
--- linux-2.4.20-pre6/arch/ia64/kernel/perfmon_generic.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/kernel/perfmon_generic.h	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,29 @@
+#define RDEP(x)	(1UL<<(x))
+
+#ifdef CONFIG_ITANIUM
+#error "This file should not be used when CONFIG_ITANIUM is defined"
+#endif
+
+static pfm_reg_desc_t pmc_desc[256]={
+/* pmc0  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pmd_desc[256]={
+/* pmd0  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd1  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd2  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd3  */ { PFM_REG_NOTIMPL, 0, NULL, NULL, {0,}, {0,}},
+/* pmd4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/perfmon_itanium.h linux-2.4.20-pre7/arch/ia64/kernel/perfmon_itanium.h
--- linux-2.4.20-pre6/arch/ia64/kernel/perfmon_itanium.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/kernel/perfmon_itanium.h	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,99 @@
+/*
+ * This file contains the Itanium PMU register description tables
+ * and pmc checker used by perfmon.c.
+ *
+ * Copyright (C) 2002  Hewlett Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#define RDEP(x)	(1UL<<(x))
+
+#ifndef CONFIG_ITANIUM
+#error "This file is only valid when CONFIG_ITANIUM is defined"
+#endif
+
+static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
+
+static pfm_reg_desc_t pmc_desc[256]={
+/* pmc0  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc10 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc11 */ { PFM_REG_MONITOR, 6, NULL, pfm_ita_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc12 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc13 */ { PFM_REG_CONFIG, 0, NULL, pfm_ita_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pmd_desc[256]={
+/* pmd0  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd1  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd2  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd3  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+/* pmd8  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd9  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd10 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd11 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd12 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd13 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd14 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd15 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd16 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd17 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static int
+pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+{
+	pfm_context_t *ctx = task->thread.pfm_context;
+	int ret;
+
+	/*
+	 * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
+		if (ret) return ret;
+	}
+
+	/*
+	 * we must clear the (data) debug registers if pmc11.pt bit is cleared
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
+		if (ret) return ret;
+	}
+	return 0;
+}
+
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/perfmon_mckinley.h linux-2.4.20-pre7/arch/ia64/kernel/perfmon_mckinley.h
--- linux-2.4.20-pre6/arch/ia64/kernel/perfmon_mckinley.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/kernel/perfmon_mckinley.h	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,134 @@
+/*
+ * This file contains the McKinley PMU register description tables
+ * and pmc checker used by perfmon.c.
+ *
+ * Copyright (C) 2002  Hewlett Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#define RDEP(x)	(1UL<<(x))
+
+#ifndef CONFIG_MCKINLEY
+#error "This file is only valid when CONFIG_MCKINLEY is defined"
+#endif
+
+static int pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
+
+static pfm_reg_desc_t pmc_desc[256]={
+/* pmc0  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc1  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc2  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc3  */ { PFM_REG_CONTROL, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc4  */ { PFM_REG_COUNTING, 6, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 6, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc10 */ { PFM_REG_MONITOR, 4, NULL, NULL, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc11 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc12 */ { PFM_REG_MONITOR, 6, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc13 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc14 */ { PFM_REG_CONFIG, 0, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc15 */ { PFM_REG_CONFIG, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static pfm_reg_desc_t pmd_desc[256]={
+/* pmd0  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd1  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}},
+/* pmd2  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd3  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+/* pmd4  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}},
+/* pmd5  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}},
+/* pmd6  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}},
+/* pmd7  */ { PFM_REG_COUNTING, 0, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}},
+/* pmd8  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd9  */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd10 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd11 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd12 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd13 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd14 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd15 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd16 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}},
+/* pmd17 */ { PFM_REG_BUFFER, 0, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}},
+	    { PFM_REG_NONE, 0, NULL, NULL, {0,}, {0,}}, /* end marker */
+};
+
+static int
+pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+{
+	struct thread_struct *th = &task->thread;
+	pfm_context_t *ctx = task->thread.pfm_context;
+	int ret = 0, check_case1 = 0;
+	unsigned long val8 = 0, val14 = 0, val13 = 0;
+
+	/*
+	 * we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled 
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 13 && (*val & (0xfUL << 45)) && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
+		if (ret) return ret;
+	}
+	/* 
+	 * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled 
+	 * before they are (fl_using_dbreg==0) to avoid picking up stale information. 
+	 */
+	if (cnum == 14 && ((*val & 0x2222) != 0x2222) && ctx->ctx_fl_using_dbreg == 0) {
+
+		/* don't mix debug with perfmon */
+		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+
+		/* 
+		 * a count of 0 will mark the debug registers as in use and also
+		 * ensure that they are properly cleared.
+		 */
+		ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
+		if (ret) return ret;
+
+	}
+
+	switch(cnum) {
+		case  4: *val |= 1UL << 23; /* force power enable bit */
+			 break;
+		case  8: val8 = *val;
+			 val13 = th->pmc[13];
+			 val14 = th->pmc[14];
+			 check_case1 = 1;
+			 break;
+		case 13: val8  = th->pmc[8];
+			 val13 = *val;
+			 val14 = th->pmc[14];
+			 check_case1 = 1;
+			 break;
+		case 14: val8  = th->pmc[13];
+			 val13 = th->pmc[13];
+			 val14 = *val;
+			 check_case1 = 1;
+			 break;
+	}
+	/* check illegal configuration which can produce inconsistencies in tagging
+	 * i-side events in L1D and L2 caches
+	 */
+	if (check_case1) {
+		ret =   ((val13 >> 45) & 0xf) == 0 
+		   && ((val8 & 0x1) == 0)
+		   && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
+		       ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
+
+		if (ret) printk("perfmon: failure check_case1\n");
+	}
+
+	return ret ? -EINVAL : 0;
+}
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/process.c linux-2.4.20-pre7/arch/ia64/kernel/process.c
--- linux-2.4.20-pre6/arch/ia64/kernel/process.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/process.c	Thu Sep 12 20:01:39 2002
@@ -18,9 +18,9 @@
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/efi.h>
 
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/perfmon.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -174,8 +174,10 @@
 # endif
 #endif
 
+#ifdef CONFIG_IA32_SUPPORT
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_save_state(task);
+#endif
 }
 
 void
@@ -194,8 +196,10 @@
 # endif
 #endif
 
+#ifdef CONFIG_IA32_SUPPORT
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_load_state(task);
+#endif
 }
 
 /*
@@ -297,21 +301,24 @@
 
 	/* copy parts of thread_struct: */
 	p->thread.ksp = (unsigned long) child_stack - 16;
+
+	/* stop some PSR bits from being inherited: */
+	child_ptregs->cr_ipsr =  ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
+				  & ~IA64_PSR_BITS_TO_CLEAR);
+
 	/*
-	 * NOTE: The calling convention considers all floating point
-	 * registers in the high partition (fph) to be scratch.  Since
-	 * the only way to get to this point is through a system call,
-	 * we know that the values in fph are all dead.  Hence, there
-	 * is no need to inherit the fph state from the parent to the
-	 * child and all we have to do is to make sure that
-	 * IA64_THREAD_FPH_VALID is cleared in the child.
+	 * NOTE: The calling convention considers all floating point registers in the high
+	 * partition (fph) to be scratch.  Since the only way to get to this point is
+	 * through a system call, we know that the values in fph are all dead.  Hence,
+	 * there is no need to inherit the fph state from the parent to the child and all
+	 * we have to do is to make sure that IA64_THREAD_FPH_VALID is cleared in the
+	 * child.
 	 *
-	 * XXX We could push this optimization a bit further by
-	 * clearing IA64_THREAD_FPH_VALID on ANY system call.
-	 * However, it's not clear this is worth doing.  Also, it
-	 * would be a slight deviation from the normal Linux system
-	 * call behavior where scratch registers are preserved across
-	 * system calls (unless used by the system call itself).
+	 * XXX We could push this optimization a bit further by clearing
+	 * IA64_THREAD_FPH_VALID on ANY system call.  However, it's not clear this is
+	 * worth doing.  Also, it would be a slight deviation from the normal Linux system
+	 * call behavior where scratch registers are preserved across system calls (unless
+	 * used by the system call itself).
 	 */
 #	define THREAD_FLAGS_TO_CLEAR	(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
 					 | IA64_THREAD_PM_VALID)
@@ -333,8 +340,11 @@
 	 */
 	atomic_set(&p->thread.pfm_notifiers_check, 0);
 	atomic_set(&p->thread.pfm_owners_check, 0);
+	/* clear list of sampling buffer to free for new task */
+	p->thread.pfm_smpl_buf_list = NULL;
 
-	if (current->thread.pfm_context) retval = pfm_inherit(p, child_ptregs);
+	if (current->thread.pfm_context)
+		retval = pfm_inherit(p, child_ptregs);
 #endif
 	return retval;
 }
@@ -537,14 +547,13 @@
 		ia64_set_fpu_owner(0);
 #endif
 #ifdef CONFIG_PERFMON
-       /* if needed, stop monitoring and flush state to perfmon context */
-	if (current->thread.pfm_context) 
+       /* stop monitoring */
+	if (current->thread.pfm_context)
 		pfm_flush_regs(current);
 
 	/* free debug register resources */
-	if ((current->thread.flags & IA64_THREAD_DBG_VALID) != 0) {
+	if (current->thread.flags & IA64_THREAD_DBG_VALID)
 		pfm_release_debug_registers(current);
-	}
 #endif
 }
 
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/salinfo.c linux-2.4.20-pre7/arch/ia64/kernel/salinfo.c
--- linux-2.4.20-pre6/arch/ia64/kernel/salinfo.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/kernel/salinfo.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,105 @@
+/*
+ * salinfo.c
+ *
+ * Creates entries in /proc/sal for various system features.
+ *
+ * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * 10/30/2001	jbarnes@sgi.com		copied much of Stephane's palinfo
+ *					code to create this file
+ */
+
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+
+#include <asm/sal.h>
+
+MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
+MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
+MODULE_LICENSE("GPL");
+
+static int salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+
+typedef struct {
+	const char		*name;		/* name of the proc entry */
+	unsigned long           feature;        /* feature bit */
+	struct proc_dir_entry	*entry;		/* registered entry (removal) */
+} salinfo_entry_t;
+
+/*
+ * List {name,feature} pairs for every entry in /proc/sal/<feature>
+ * that this module exports
+ */
+static salinfo_entry_t salinfo_entries[]={
+	{ "bus_lock",           IA64_SAL_PLATFORM_FEATURE_BUS_LOCK, },
+	{ "irq_redirection",	IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT, },
+	{ "ipi_redirection",	IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT, },
+	{ "itc_drift",		IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT, },
+};
+
+#define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t))
+
+/*
+ * One for each feature and one more for the directory entry...
+ */
+static struct proc_dir_entry *salinfo_proc_entries[NR_SALINFO_ENTRIES + 1];
+
+static int __init
+salinfo_init(void)
+{
+	struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */
+	struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */
+	int i;
+
+	salinfo_dir = proc_mkdir("sal", NULL);
+
+	for (i=0; i < NR_SALINFO_ENTRIES; i++) {
+		/* pass the feature bit in question as misc data */
+		*sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
+						  salinfo_read, (void *)salinfo_entries[i].feature);
+	}
+	*sdir++ = salinfo_dir;
+
+	return 0;
+}
+
+static void __exit
+salinfo_exit(void)
+{
+	int i = 0;
+
+	for (i = 0; i < NR_SALINFO_ENTRIES ; i++) {
+		if (salinfo_proc_entries[i])
+			remove_proc_entry (salinfo_proc_entries[i]->name, NULL);
+	}
+}
+
+/*
+ * 'data' contains an integer that corresponds to the feature we're
+ * testing
+ */
+static int
+salinfo_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+
+	len = sprintf(page, (sal_platform_features & (unsigned long)data) ? "1\n" : "0\n");
+
+	if (len <= off+count) *eof = 1;
+
+	*start = page + off;
+	len   -= off;
+
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+module_init(salinfo_init);
+module_exit(salinfo_exit);
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/setup.c linux-2.4.20-pre7/arch/ia64/kernel/setup.c
--- linux-2.4.20-pre6/arch/ia64/kernel/setup.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/setup.c	Thu Sep 12 20:01:39 2002
@@ -19,6 +19,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 
+#include <linux/acpi.h>
 #include <linux/bootmem.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
@@ -28,15 +29,15 @@
 #include <linux/string.h>
 #include <linux/threads.h>
 #include <linux/console.h>
+#include <linux/ioport.h>
+#include <linux/efi.h>
 
-#include <asm/acpi-ext.h>
 #include <asm/ia32.h>
 #include <asm/page.h>
 #include <asm/machvec.h>
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/system.h>
-#include <asm/efi.h>
 #include <asm/mca.h>
 #include <asm/smp.h>
 
@@ -65,6 +66,8 @@
 
 unsigned long ia64_iobase;	/* virtual address for I/O accesses */
 
+unsigned char aux_device_present = 0xaa;        /* XXX remove this when legacy I/O is gone */
+
 #define COMMAND_LINE_SIZE	512
 
 char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */
@@ -283,6 +286,7 @@
 setup_arch (char **cmdline_p)
 {
 	extern unsigned long ia64_iobase;
+	unsigned long phys_iobase;
 
 	unw_init();
 
@@ -292,6 +296,7 @@
 
 	efi_init();
 
+	iomem_resource.end = ~0UL;	/* FIXME probably belongs elsewhere */
 	find_memory();
 
 #if 0
@@ -315,24 +320,23 @@
 #endif
 
 	/*
-	 *  Set `iobase' to the appropriate address in region 6
-	 *    (uncached access range)
+	 *  Set `iobase' to the appropriate address in region 6 (uncached access range).
 	 *
-	 *  The EFI memory map is the "prefered" location to get the I/O port
-	 *  space base, rather the relying on AR.KR0. This should become more
-	 *  clear in future SAL specs. We'll fall back to getting it out of
-	 *  AR.KR0 if no appropriate entry is found in the memory map.
+	 *  The EFI memory map is the "preferred" location to get the I/O port space base,
+	 *  rather the relying on AR.KR0. This should become more clear in future SAL
+	 *  specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
+	 *  found in the memory map.
 	 */
-	ia64_iobase = efi_get_iobase();
-	if (ia64_iobase)
+	phys_iobase = efi_get_iobase();
+	if (phys_iobase)
 		/* set AR.KR0 since this is all we use it for anyway */
-		ia64_set_kr(IA64_KR_IO_BASE, ia64_iobase);
+		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
 	else {
-		ia64_iobase = ia64_get_kr(IA64_KR_IO_BASE);
+		phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
 		printk("No I/O port range found in EFI memory map, falling back to AR.KR0\n");
-		printk("I/O port base = 0x%lx\n", ia64_iobase);
+		printk("I/O port base = 0x%lx\n", phys_iobase);
 	}
-	ia64_iobase = __IA64_UNCACHED_OFFSET | (ia64_iobase & ~PAGE_OFFSET);
+	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
 
 #ifdef CONFIG_SMP
 	cpu_physical_id(0) = hard_smp_processor_id();
@@ -340,24 +344,31 @@
 
 	cpu_init();	/* initialize the bootstrap CPU */
 
-	if (efi.acpi20) {
-		/* Parse the ACPI 2.0 tables */
-		acpi20_parse(efi.acpi20);
-	} else if (efi.acpi) {
-		/* Parse the ACPI tables */
-		acpi_parse(efi.acpi);
-	}
+#ifdef CONFIG_ACPI_BOOT
+	acpi_boot_init(*cmdline_p);
+#endif
+#ifdef CONFIG_SERIAL_HCDP
 	if (efi.hcdp) {
+		void setup_serial_hcdp(void *);
+
 		/* Setup the serial ports described by HCDP */
 		setup_serial_hcdp(efi.hcdp);
 	}
-
+#endif
 #ifdef CONFIG_VT
-# if defined(CONFIG_VGA_CONSOLE)
-	conswitchp = &vga_con;
-# elif defined(CONFIG_DUMMY_CONSOLE)
+# if defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
 # endif
+# if defined(CONFIG_VGA_CONSOLE)
+	/*
+	 * Non-legacy systems may route legacy VGA MMIO range to system
+	 * memory.  vga_con probes the MMIO hole, so memory looks like
+	 * a VGA device to it.  The EFI memory map can tell us if it's
+	 * memory so we can avoid this problem.
+	 */
+	if (efi_mem_type(0xA0000) != EFI_CONVENTIONAL_MEMORY)
+		conswitchp = &vga_con;
+# endif
 #endif
 
 #ifdef CONFIG_IA64_MCA
@@ -392,7 +403,7 @@
 
 	switch (c->family) {
 	      case 0x07:	memcpy(family, "Itanium", 8); break;
-	      case 0x1f:	memcpy(family, "McKinley", 9); break;
+	      case 0x1f:	memcpy(family, "Itanium 2", 10); break;
 	      default:		sprintf(family, "%u", c->family); break;
 	}
 
@@ -433,7 +444,7 @@
 c_start (struct seq_file *m, loff_t *pos)
 {
 #ifdef CONFIG_SMP
-	while (*pos < NR_CPUS && !(cpu_online_map & (1 << *pos)))
+	while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos)))
 		++*pos;
 #endif
 	return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
@@ -570,6 +581,24 @@
 	 */
 	identify_cpu(my_cpu_data);
 
+#ifdef CONFIG_MCKINLEY
+	{
+#define FEATURE_SET 16
+		struct ia64_pal_retval iprv;
+
+		if (my_cpu_data->family == 0x1f) {
+
+			PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, FEATURE_SET, 0);
+
+			if ((iprv.status == 0) && (iprv.v0 & 0x80) && (iprv.v2 & 0x80)) {
+
+				PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES,
+				              (iprv.v1 | 0x80), FEATURE_SET, 0);
+			}
+		}
+	}
+#endif
+
 	/* Clear the stack memory reserved for pt_regs: */
 	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
 
@@ -581,7 +610,7 @@
 	 * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll
 	 * be fine).
 	 */
-	ia64_set_dcr(  IA64_DCR_DM | IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
+	ia64_set_dcr(  IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
 		     | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC);
 #ifndef CONFIG_SMP
 	ia64_set_fpu_owner(0);
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/signal.c linux-2.4.20-pre7/arch/ia64/kernel/signal.c
--- linux-2.4.20-pre6/arch/ia64/kernel/signal.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/signal.c	Thu Sep 12 20:01:39 2002
@@ -143,9 +143,11 @@
 {
 	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 {
+	if (from->si_code < 0) {
+		if (__copy_to_user(to, from, sizeof(siginfo_t)))
+			return -EFAULT;
+		return 0;
+	} else {
 		int err;
 
 		/*
@@ -559,7 +561,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:
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/smp.c linux-2.4.20-pre7/arch/ia64/kernel/smp.c
--- linux-2.4.20-pre6/arch/ia64/kernel/smp.c	Fri Dec 21 09:41:53 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/smp.c	Thu Sep 12 20:01:39 2002
@@ -31,12 +31,12 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/cache.h>
+#include <linux/efi.h>
 
 #include <asm/atomic.h>
 #include <asm/bitops.h>
 #include <asm/current.h>
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/machvec.h>
 
 #include <asm/io.h>
@@ -90,7 +90,7 @@
 handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
 {
 	int this_cpu = smp_processor_id();
-	unsigned long *pending_ipis = &local_cpu_data->ipi_operation;
+	unsigned long *pending_ipis = &local_cpu_data->ipi.operation;
 	unsigned long ops;
 
 	/* Count this now; we may make a call that never returns. */
@@ -149,7 +149,7 @@
 static inline void
 send_IPI_single (int dest_cpu, int op)
 {
-	set_bit(op, &cpu_data(dest_cpu)->ipi_operation);
+	set_bit(op, &cpu_data(dest_cpu)->ipi.operation);
 	platform_send_ipi(dest_cpu, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
@@ -212,7 +212,7 @@
 	int cpus = 1;
 
 	if (cpuid == smp_processor_id()) {
-		printk(__FUNCTION__" trying to call self\n");
+		printk("%s: trying to call self\n", __FUNCTION__);
 		return -EBUSY;
 	}
 
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/smpboot.c linux-2.4.20-pre7/arch/ia64/kernel/smpboot.c
--- linux-2.4.20-pre6/arch/ia64/kernel/smpboot.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/smpboot.c	Thu Sep 12 20:01:39 2002
@@ -23,13 +23,13 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
+#include <linux/efi.h>
 
 #include <asm/atomic.h>
 #include <asm/bitops.h>
 #include <asm/cache.h>
 #include <asm/current.h>
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/machvec.h>
@@ -68,6 +68,7 @@
 
 extern void __init calibrate_delay(void);
 extern void start_ap(void);
+extern unsigned long ia64_iobase;
 
 int cpucount;
 
@@ -344,6 +345,11 @@
 	 */
 	ia64_init_itm();
 
+	/*
+	 * Set I/O port base per CPU
+	 */
+	ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
+
 #ifdef CONFIG_IA64_MCA
 	ia64_mca_cmc_vector_setup();	/* Setup vector on AP & enable */
 	ia64_mca_check_errors();	/* For post-failure MCA error logging */
@@ -528,11 +534,11 @@
 
 		printk("Before bogomips.\n");
 		if (!cpucount) {
-			printk(KERN_ERR "Error: only one processor found.\n");
+			printk(KERN_WARNING "Warning: only one processor found.\n");
 		} else {
 			unsigned long bogosum = 0;
   			for (cpu = 0; cpu < NR_CPUS; cpu++)
-				if (cpu_online_map & (1<<cpu))
+				if (cpu_online_map & (1UL << cpu))
 					bogosum += cpu_data(cpu)->loops_per_jiffy;
 
 			printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/sys_ia64.c linux-2.4.20-pre7/arch/ia64/kernel/sys_ia64.c
--- linux-2.4.20-pre6/arch/ia64/kernel/sys_ia64.c	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/kernel/sys_ia64.c	Thu Sep 12 20:01:39 2002
@@ -2,8 +2,8 @@
  * This file contains various system calls that have different calling
  * conventions on different platforms.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -201,15 +201,13 @@
 	if (len == 0)
 		goto out;
 
-	/* don't permit mappings into unmapped space or the virtual page table of a region: */
+	/*
+	 * Don't permit mappings into unmapped space, the virtual page table of a region,
+	 * or across a region boundary.  Note: RGN_MAP_LIMIT is equal to 2^n-PAGE_SIZE
+	 * (for some integer n <= 61) and len > 0.
+	 */
 	roff = rgn_offset(addr);
-	if ((len | roff | (roff + len)) >= RGN_MAP_LIMIT) {
-		addr = -EINVAL;
-		goto out;
-	}
-
-	/* don't permit mappings that would cross a region boundary: */
-	if (rgn_index(addr) != rgn_index(addr + len)) {
+	if ((len > RGN_MAP_LIMIT) || (roff > (RGN_MAP_LIMIT - len))) {
 		addr = -EINVAL;
 		goto out;
 	}
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/time.c linux-2.4.20-pre7/arch/ia64/kernel/time.c
--- linux-2.4.20-pre6/arch/ia64/kernel/time.c	Mon Feb 25 11:37:53 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/time.c	Thu Sep 12 20:01:39 2002
@@ -15,9 +15,9 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
+#include <linux/efi.h>
 
 #include <asm/delay.h>
-#include <asm/efi.h>
 #include <asm/hw_irq.h>
 #include <asm/ptrace.h>
 #include <asm/sal.h>
@@ -39,21 +39,22 @@
 	extern unsigned long prof_cpu_mask;
 	extern char _stext;
 
+	if (!prof_buffer)
+		return;
+
 	if (!((1UL << smp_processor_id()) & prof_cpu_mask))
 		return;
 
-	if (prof_buffer && current->pid) {
-		ip -= (unsigned long) &_stext;
-		ip >>= prof_shift;
-		/*
-		 * Don't ignore out-of-bounds IP values silently, put them into the last
-		 * histogram slot, so if present, they will show up as a sharp peak.
-		 */
-		if (ip > prof_len - 1)
-			ip = prof_len - 1;
+	ip -= (unsigned long) &_stext;
+	ip >>= prof_shift;
+	/*
+	 * Don't ignore out-of-bounds IP values silently, put them into the last
+	 * histogram slot, so if present, they will show up as a sharp peak.
+	 */
+	if (ip > prof_len - 1)
+		ip = prof_len - 1;
 
-		atomic_inc((atomic_t *) &prof_buffer[ip]);
-	}
+	atomic_inc((atomic_t *) &prof_buffer[ip]);
 }
 
 /*
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/traps.c linux-2.4.20-pre7/arch/ia64/kernel/traps.c
--- linux-2.4.20-pre6/arch/ia64/kernel/traps.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/traps.c	Thu Sep 12 20:01:39 2002
@@ -48,10 +48,15 @@
 void __init
 trap_init (void)
 {
-	printk("fpswa interface at %lx\n", ia64_boot_param->fpswa);
-	if (ia64_boot_param->fpswa)
+	if (ia64_boot_param->fpswa) {
 		/* FPSWA fixup: make the interface pointer a kernel virtual address: */
 		fpswa_interface = __va(ia64_boot_param->fpswa);
+		printk("FPSWA interface at 0x%lx, revision %d.%d\n",
+			ia64_boot_param->fpswa,
+			fpswa_interface->revision >> 16,
+			fpswa_interface->revision & 0xffff);
+	} else
+		printk("No FPSWA interface\n");
 }
 
 /*
@@ -185,6 +190,10 @@
 		sig = SIGSEGV; code = __SEGV_PSTKOVF;
 		break;
 
+	      case 0x3f000 ... 0x3ffff:	/* bundle-update in progress */
+		sig = SIGILL; code = __ILL_BNDMOD;
+		break;
+
 	      default:
 		if (break_num < 0x40000 || break_num > 0x100000)
 			die_if_kernel("Bad break", regs, break_num);
@@ -213,7 +222,8 @@
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
 
-	printk("<sc%ld(%lx,%lx,%lx,%lx)>\n", regs->r15, arg0, arg1, arg2, arg3);
+	printk("%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
+	       regs->r15, arg0, arg1, arg2, arg3);
 	return -ENOSYS;
 }
 
@@ -242,9 +252,9 @@
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
 
-		ia64_set_fpu_owner(current);
 	}
 #endif /* !CONFIG_SMP */
+	ia64_set_fpu_owner(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
 		__ia64_load_fpu(current->thread.fph);
 		psr->mfh = 0;
@@ -429,7 +439,7 @@
 	unsigned long code, error = isr;
 	struct siginfo siginfo;
 	char buf[128];
-	int result;
+	int result, sig;
 	static const char *reason[] = {
 		"IA-64 Illegal Operation fault",
 		"IA-64 Privileged Operation fault",
@@ -441,30 +451,14 @@
 		"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
 	};
 
-#if 0
-	/* this is for minimal trust debugging; yeah this kind of stuff is useful at times... */
-
-	if (vector != 25) {
-		static unsigned long last_time;
-		static char count;
-		unsigned long n = vector;
-		char buf[32], *cp;
-
-		if (jiffies - last_time > 5*HZ)
-			count = 0;
-
-		if (count++ < 5) {
-			last_time = jiffies;
-			cp = buf + sizeof(buf);
-			*--cp = '\0';
-			while (n) {
-				*--cp = "0123456789abcdef"[n & 0xf];
-				n >>= 4;
-			}
-			printk("<0x%s>", cp);
-		}
+	if ((isr & IA64_ISR_NA) && ((isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) {
+		/*
+		 * This fault was due to lfetch.fault, set "ed" bit in the psr to cancel
+		 * the lfetch.
+		 */
+		ia64_psr(regs)->ed = 1;
+		return;
 	}
-#endif
 
 	switch (vector) {
 	      case 24: /* General Exception */
@@ -489,6 +483,30 @@
 		break;
 
 	      case 26: /* NaT Consumption */
+		if (user_mode(regs)) {
+			if (((isr >> 4) & 0xf) == 2) {
+				/* NaT page consumption */
+				sig = SIGSEGV;
+				code = SEGV_ACCERR;
+			} else {
+				/* register NaT consumption */
+				sig = SIGILL;
+				code = ILL_ILLOPN;
+			}
+			siginfo.si_signo = sig;
+			siginfo.si_code = code;
+			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(sig, &siginfo, current);
+			return;
+		} else if (done_with_exception(regs))
+			return;
+		sprintf(buf, "NaT consumption");
+		break;
+
 	      case 31: /* Unsupported Data Reference */
 		if (user_mode(regs)) {
 			siginfo.si_signo = SIGILL;
@@ -501,7 +519,7 @@
 			force_sig_info(SIGILL, &siginfo, current);
 			return;
 		}
-		sprintf(buf, (vector == 26) ? "NaT consumption" : "Unsupported data reference");
+		sprintf(buf, "Unsupported data reference");
 		break;
 
 	      case 29: /* Debug */
@@ -518,16 +536,15 @@
 			if (ia64_psr(regs)->is == 0)
 			  ifa = regs->cr_iip;
 #endif
-			siginfo.si_addr = (void *) ifa;
 			break;
-		      case 35: siginfo.si_code = TRAP_BRANCH; break;
-		      case 36: siginfo.si_code = TRAP_TRACE; break;
+		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
+		      case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
 		}
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
 		siginfo.si_flags = 0;
 		siginfo.si_isr = 0;
-		siginfo.si_addr = 0;
+		siginfo.si_addr = (void *) ifa;
 		siginfo.si_imm = 0;
 		force_sig_info(SIGTRAP, &siginfo, current);
 		return;
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/unaligned.c linux-2.4.20-pre7/arch/ia64/kernel/unaligned.c
--- linux-2.4.20-pre6/arch/ia64/kernel/unaligned.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/unaligned.c	Thu Sep 12 20:01:39 2002
@@ -1304,11 +1304,7 @@
 	 * handler into reading an arbitrary kernel addresses...
 	 */
 	if (!user_mode(regs)) {
-#ifdef GAS_HAS_LOCAL_TAGS
-		fix = search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
-#else
-		fix = search_exception_table(regs->cr_iip);
-#endif
+		fix = SEARCH_EXCEPTION_TABLE(regs);
 	}
 	if (user_mode(regs) || fix.cont) {
 		if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/unwind.c linux-2.4.20-pre7/arch/ia64/kernel/unwind.c
--- linux-2.4.20-pre6/arch/ia64/kernel/unwind.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/unwind.c	Thu Sep 12 20:01:39 2002
@@ -634,8 +634,8 @@
 	for (reg = hi; reg >= lo; --reg) {
 		if (reg->where == UNW_WHERE_SPILL_HOME) {
 			reg->where = UNW_WHERE_PSPREL;
-			reg->val = 0x10 - *offp;
-			*offp += regsize;
+			*offp -= regsize;
+			reg->val = *offp;
 		}
 	}
 }
@@ -814,7 +814,8 @@
 	}
 	for (i = 0; i < 20; ++i) {
 		if ((frmask & 1) != 0) {
-			set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
+			int base = (i < 4) ? UNW_REG_F2 : UNW_REG_F16 - 4;
+			set_reg(sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
 				sr->region_start + sr->region_len - 1, 0);
 			sr->any_spills = 1;
 		}
diff -urN linux-2.4.20-pre6/arch/ia64/kernel/unwind_i.h linux-2.4.20-pre7/arch/ia64/kernel/unwind_i.h
--- linux-2.4.20-pre6/arch/ia64/kernel/unwind_i.h	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/kernel/unwind_i.h	Thu Sep 12 20:01:39 2002
@@ -103,7 +103,7 @@
 	unsigned int in_body : 1;	/* are we inside a body (as opposed to a prologue)? */
 	unsigned long flags;		/* see UNW_FLAG_* in unwind.h */
 
-	u8 *imask;			/* imask of of spill_mask record or NULL */
+	u8 *imask;			/* imask of spill_mask record or NULL */
 	unsigned long pr_val;		/* predicate values */
 	unsigned long pr_mask;		/* predicate mask */
 	long spill_offset;		/* psp-relative offset for spill base */
diff -urN linux-2.4.20-pre6/arch/ia64/lib/Makefile linux-2.4.20-pre7/arch/ia64/lib/Makefile
--- linux-2.4.20-pre6/arch/ia64/lib/Makefile	Tue Jul 31 10:30:08 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/Makefile	Thu Sep 12 20:01:39 2002
@@ -11,10 +11,13 @@
 
 obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o					\
 	__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o					\
-	checksum.o clear_page.o csum_partial_copy.o copy_page.o				\
-	copy_user.o clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o	\
-	flush.o io.o do_csum.o								\
-	memcpy.o memset.o strlen.o swiotlb.o
+	checksum.o clear_page.o csum_partial_copy.o					\
+	clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o			\
+	flush.o ip_fast_csum.o io.o do_csum.o						\
+	memset.o strlen.o swiotlb.o
+
+obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
+obj-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
 
 IGNORE_FLAGS_OBJS =	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
 			__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
diff -urN linux-2.4.20-pre6/arch/ia64/lib/checksum.c linux-2.4.20-pre7/arch/ia64/lib/checksum.c
--- linux-2.4.20-pre6/arch/ia64/lib/checksum.c	Tue Jul 31 10:30:08 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/checksum.c	Thu Sep 12 20:01:39 2002
@@ -66,15 +66,6 @@
 extern unsigned long do_csum (const unsigned char *, long);
 
 /*
- *	This is a version of ip_compute_csum() optimized for IP headers,
- *	which always checksum on 4 octet boundaries.
- */
-unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
-{
-	return ~do_csum(iph, ihl*4);
-}
-
-/*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
  *
diff -urN linux-2.4.20-pre6/arch/ia64/lib/clear_page.S linux-2.4.20-pre7/arch/ia64/lib/clear_page.S
--- linux-2.4.20-pre6/arch/ia64/lib/clear_page.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/clear_page.S	Thu Sep 12 20:01:39 2002
@@ -1,51 +1,77 @@
 /*
- *
- * Optimized function to clear a page of memory.
- *
- * Inputs:
- *	in0:	address of page
- *
- * Output:
- * 	none
- *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999-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>
+ * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
  *
  * 1/06/01 davidm	Tuned for Itanium.
+ * 2/12/02 kchen	Tuned for both Itanium and McKinley
+ * 3/08/02 davidm	Some more tweaking
  */
+#include <linux/config.h>
+
 #include <asm/asmmacro.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_ITANIUM
+# define L3_LINE_SIZE	64	// Itanium L3 line size
+# define PREFETCH_LINES	9	// magic number
+#else
+# define L3_LINE_SIZE	128	// McKinley L3 line size
+# define PREFETCH_LINES	12	// magic number
+#endif
+
 #define saved_lc	r2
-#define dst0		in0
+#define dst_fetch	r3
 #define dst1		r8
 #define dst2		r9
 #define dst3		r10
-#define dst_fetch	r11
+#define dst4		r11
+
+#define dst_last	r31
 
 GLOBAL_ENTRY(clear_page)
 	.prologue
 	.regstk 1,0,0,0
-	mov r16 = PAGE_SIZE/64-1	// -1 = repeat/until
-	;;
+	mov r16 = PAGE_SIZE/L3_LINE_SIZE-1	// main loop count, -1=repeat/until
 	.save ar.lc, saved_lc
 	mov saved_lc = ar.lc
+
 	.body
-	mov ar.lc = r16
-	adds dst1 = 16, dst0
-	adds dst2 = 32, dst0
-	adds dst3 = 48, dst0
-	adds dst_fetch = 512, dst0
+	mov ar.lc = (PREFETCH_LINES - 1)
+	mov dst_fetch = in0
+	adds dst1 = 16, in0
+	adds dst2 = 32, in0
+	;;
+.fetch:	stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
+	adds dst3 = 48, in0		// executing this multiple times is harmless
+	br.cloop.sptk.few .fetch
+	;;
+	addl dst_last = (PAGE_SIZE - PREFETCH_LINES*L3_LINE_SIZE), dst_fetch
+	mov ar.lc = r16			// one L3 line per iteration
+	adds dst4 = 64, in0
+	;;
+#ifdef CONFIG_ITANIUM
+	// Optimized for Itanium
+1:	stf.spill.nta [dst1] = f0, 64
+	stf.spill.nta [dst2] = f0, 64
+	cmp.lt p8,p0=dst_fetch, dst_last
+	;;
+#else
+	// Optimized for McKinley
+1:	stf.spill.nta [dst1] = f0, 64
+	stf.spill.nta [dst2] = f0, 64
+	stf.spill.nta [dst3] = f0, 64
+	stf.spill.nta [dst4] = f0, 128
+	cmp.lt p8,p0=dst_fetch, dst_last
 	;;
-1:	stf.spill.nta [dst0] = f0, 64
 	stf.spill.nta [dst1] = f0, 64
 	stf.spill.nta [dst2] = f0, 64
+#endif
 	stf.spill.nta [dst3] = f0, 64
-
-	lfetch [dst_fetch], 64
-	br.cloop.dptk.few 1b
+(p8)	stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
+	br.cloop.sptk.few 1b
 	;;
-	mov ar.lc = r2		// restore lc
+	mov ar.lc = saved_lc		// restore lc
 	br.ret.sptk.many rp
 END(clear_page)
diff -urN linux-2.4.20-pre6/arch/ia64/lib/copy_page.S linux-2.4.20-pre7/arch/ia64/lib/copy_page.S
--- linux-2.4.20-pre6/arch/ia64/lib/copy_page.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/copy_page.S	Thu Sep 12 20:01:39 2002
@@ -30,6 +30,7 @@
 #define tgt2		r23
 #define srcf		r24
 #define tgtf		r25
+#define tgt_last	r26
 
 #define Nrot		((8*PIPE_DEPTH+7)&~7)
 
@@ -55,18 +56,21 @@
 
 	mov src1=in1
 	adds src2=8,in1
+	mov tgt_last = PAGE_SIZE
 	;;
 	adds tgt2=8,in0
 	add srcf=512,in1
 	mov ar.lc=lcount
 	mov tgt1=in0
 	add tgtf=512,in0
+	add tgt_last = tgt_last, in0
 	;;
 1:
 (p[0])	ld8 t1[0]=[src1],16
 (EPI)	st8 [tgt1]=t1[PIPE_DEPTH-1],16
 (p[0])	ld8 t2[0]=[src2],16
 (EPI)	st8 [tgt2]=t2[PIPE_DEPTH-1],16
+	cmp.ltu p6,p0 = tgtf, tgt_last
 	;;
 (p[0])	ld8 t3[0]=[src1],16
 (EPI)	st8 [tgt1]=t3[PIPE_DEPTH-1],16
@@ -83,8 +87,8 @@
 (p[0])	ld8 t8[0]=[src2],16
 (EPI)	st8 [tgt2]=t8[PIPE_DEPTH-1],16
 
-	lfetch [srcf], 64
-	lfetch [tgtf], 64
+(p6)	lfetch [srcf], 64
+(p6)	lfetch [tgtf], 64
 	br.ctop.sptk.few 1b
 	;;
 	mov pr=saved_pr,0xffffffffffff0000	// restore predicates
diff -urN linux-2.4.20-pre6/arch/ia64/lib/copy_page_mck.S linux-2.4.20-pre7/arch/ia64/lib/copy_page_mck.S
--- linux-2.4.20-pre6/arch/ia64/lib/copy_page_mck.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/lib/copy_page_mck.S	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,185 @@
+/*
+ * McKinley-optimized version of copy_page().
+ *
+ * Copyright (C) 2002 Hewlett-Packard Co
+ *	David Mosberger <davidm@hpl.hp.com>
+ *
+ * Inputs:
+ *	in0:	address of target page
+ *	in1:	address of source page
+ * Output:
+ *	no return value
+ *
+ * General idea:
+ *	- use regular loads and stores to prefetch data to avoid consuming M-slot just for
+ *	  lfetches => good for in-cache performance
+ *	- avoid l2 bank-conflicts by not storing into the same 16-byte bank within a single
+ *	  cycle
+ *
+ * Principle of operation:
+ *	First, note that L1 has a line-size of 64 bytes and L2 a line-size of 128 bytes.
+ *	To avoid secondary misses in L2, we prefetch both source and destination with a line-size
+ *	of 128 bytes.  When both of these lines are in the L2 and the first half of the
+ *	source line is in L1, we start copying the remaining words.  The second half of the
+ *	source line is prefetched in an earlier iteration, so that by the time we start
+ *	accessing it, it's also present in the L1.
+ *
+ *	We use a software-pipelined loop to control the overall operation.  The pipeline
+ *	has 2*PREFETCH_DIST+K stages.  The first PREFETCH_DIST stages are used for prefetching
+ *	source cache-lines.  The second PREFETCH_DIST stages are used for prefetching destination
+ *	cache-lines, the last K stages are used to copy the cache-line words not copied by
+ *	the prefetches.  The four relevant points in the pipelined are called A, B, C, D:
+ *	p[A] is TRUE if a source-line should be prefetched, p[B] is TRUE if a destination-line
+ *	should be prefetched, p[C] is TRUE if the second half of an L2 line should be brought
+ *	into L1D and p[D] is TRUE if a cacheline needs to be copied.
+ *
+ *	This all sounds very complicated, but thanks to the modulo-scheduled loop support,
+ *	the resulting code is very regular and quite easy to follow (once you get the idea).
+ *
+ *	As a secondary optimization, the first 2*PREFETCH_DIST iterations are implemented
+ *	as the separate .prefetch_loop.  Logically, this loop performs exactly like the
+ *	main-loop (.line_copy), but has all known-to-be-predicated-off instructions removed,
+ *	so that each loop iteration is faster (again, good for cached case).
+ *
+ *	When reading the code, it helps to keep the following picture in mind:
+ *
+ *	       word 0 word 1
+ *            +------+------+---
+ *	      |	v[x] | 	t1  | ^
+ *	      |	t2   |	t3  | |
+ *	      |	t4   |	t5  | |
+ *	      |	t6   |	t7  | | 128 bytes
+ *     	      |	n[y] | 	t9  | |	(L2 cache line)
+ *	      |	t10  | 	t11 | |
+ *	      |	t12  | 	t13 | |
+ *	      |	t14  | 	t15 | v
+ *	      +------+------+---
+ *
+ *	Here, v[x] is copied by the (memory) prefetch.  n[y] is loaded at p[C]
+ *	to fetch the second-half of the L2 cache line into L1, and the tX words are copied in
+ *	an order that avoids bank conflicts.
+ */
+#include <asm/asmmacro.h>
+#include <asm/page.h>
+
+#define PREFETCH_DIST	8		// McKinley sustains 16 outstanding L2 misses (8 ld, 8 st)
+
+#define src0		r2
+#define src1		r3
+#define dst0		r9
+#define dst1		r10
+#define src_pre_mem	r11
+#define dst_pre_mem	r14
+#define src_pre_l2	r15
+#define dst_pre_l2	r16
+#define t1		r17
+#define t2		r18
+#define t3		r19
+#define t4		r20
+#define t5		t1	// alias!
+#define t6		t2	// alias!
+#define t7		t3	// alias!
+#define t9		t5	// alias!
+#define t10		t4	// alias!
+#define t11		t7	// alias!
+#define t12		t6	// alias!
+#define t14		t10	// alias!
+#define t13		r21
+#define t15		r22
+
+#define saved_lc	r23
+#define saved_pr	r24
+
+#define	A	0
+#define B	(PREFETCH_DIST)
+#define C	(B + PREFETCH_DIST)
+#define D	(C + 3)
+#define N	(D + 1)
+#define Nrot	((N + 7) & ~7)
+
+GLOBAL_ENTRY(copy_page)
+	.prologue
+	alloc r8 = ar.pfs, 2, Nrot-2, 0, Nrot
+
+	.rotr v[2*PREFETCH_DIST], n[D-C+1]
+	.rotp p[N]
+
+	.save ar.lc, saved_lc
+	mov saved_lc = ar.lc
+	.save pr, saved_pr
+	mov saved_pr = pr
+	.body
+
+	mov src_pre_mem = in1
+	mov pr.rot = 0x10000
+	mov ar.ec = 1				// special unrolled loop
+
+	mov dst_pre_mem = in0
+	mov ar.lc = 2*PREFETCH_DIST - 1
+
+	add src_pre_l2 = 8*8, in1
+	add dst_pre_l2 = 8*8, in0
+	add src0 = 8, in1			// first t1 src
+	add src1 = 3*8, in1			// first t3 src
+	add dst0 = 8, in0			// first t1 dst
+	add dst1 = 3*8, in0			// first t3 dst
+	mov t1 = (PAGE_SIZE/128) - (2*PREFETCH_DIST) - 1
+	nop.m 0
+	nop.i 0
+	;;
+	// same as .line_copy loop, but with all predicated-off instructions removed:
+.prefetch_loop:
+(p[A])	ld8 v[A] = [src_pre_mem], 128		// M0
+(p[B])	st8 [dst_pre_mem] = v[B], 128		// M2
+	br.ctop.sptk .prefetch_loop
+	;;
+	cmp.eq p16, p0 = r0, r0			// reset p16 to 1 (br.ctop cleared it to zero)
+	mov ar.lc = t1				// with 64KB pages, t1 is too big to fit in 8 bits!
+	mov ar.ec = N				// # of stages in pipeline
+	;;
+.line_copy:
+(p[D])	ld8 t2 = [src0], 3*8			// M0
+(p[D])	ld8 t4 = [src1], 3*8			// M1
+(p[B])	st8 [dst_pre_mem] = v[B], 128		// M2 prefetch dst from memory
+(p[D])	st8 [dst_pre_l2] = n[D-C], 128		// M3 prefetch dst from L2
+	;;
+(p[A])	ld8 v[A] = [src_pre_mem], 128		// M0 prefetch src from memory
+(p[C])	ld8 n[0] = [src_pre_l2], 128		// M1 prefetch src from L2
+(p[D])	st8 [dst0] =  t1, 8			// M2
+(p[D])	st8 [dst1] =  t3, 8			// M3
+	;;
+(p[D])	ld8  t5 = [src0], 8
+(p[D])	ld8  t7 = [src1], 3*8
+(p[D])	st8 [dst0] =  t2, 3*8
+(p[D])	st8 [dst1] =  t4, 3*8
+	;;
+(p[D])	ld8  t6 = [src0], 3*8
+(p[D])	ld8 t10 = [src1], 8
+(p[D])	st8 [dst0] =  t5, 8
+(p[D])	st8 [dst1] =  t7, 3*8
+	;;
+(p[D])	ld8  t9 = [src0], 3*8
+(p[D])	ld8 t11 = [src1], 3*8
+(p[D])	st8 [dst0] =  t6, 3*8
+(p[D])	st8 [dst1] = t10, 8
+	;;
+(p[D])	ld8 t12 = [src0], 8
+(p[D])	ld8 t14 = [src1], 8
+(p[D])	st8 [dst0] =  t9, 3*8
+(p[D])	st8 [dst1] = t11, 3*8
+	;;
+(p[D])	ld8 t13 = [src0], 4*8
+(p[D])	ld8 t15 = [src1], 4*8
+(p[D])	st8 [dst0] = t12, 8
+(p[D])	st8 [dst1] = t14, 8
+	;;
+(p[D-1])ld8  t1 = [src0], 8
+(p[D-1])ld8  t3 = [src1], 8
+(p[D])	st8 [dst0] = t13, 4*8
+(p[D])	st8 [dst1] = t15, 4*8
+	br.ctop.sptk .line_copy
+	;;
+	mov ar.lc = saved_lc
+	mov pr = saved_pr, -1
+	br.ret.sptk.many rp
+END(copy_page)
diff -urN linux-2.4.20-pre6/arch/ia64/lib/copy_user.S linux-2.4.20-pre7/arch/ia64/lib/copy_user.S
--- linux-2.4.20-pre6/arch/ia64/lib/copy_user.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/copy_user.S	Thu Sep 12 20:01:39 2002
@@ -237,15 +237,17 @@
 .copy_user_bit##rshift:						\
 1:								\
 	EX(.failure_out,(EPI) st8 [dst1]=tmp,8);		\
-(EPI_1) shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift;	\
-	EX(3f,(p16) ld8 val1[0]=[src1],8);			\
+(EPI_1) shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift;	\
+	EX(3f,(p16) ld8 val1[1]=[src1],8);			\
+(p16)	mov val1[0]=r0;						\
 	br.ctop.dptk 1b;					\
 	;;							\
 	br.cond.sptk.many .diff_align_do_tail;			\
 2:								\
 (EPI)	st8 [dst1]=tmp,8;					\
-(EPI_1)	shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift;	\
+(EPI_1)	shrp tmp=val1[PIPE_DEPTH-2],val1[PIPE_DEPTH-1],rshift;	\
 3:								\
+(p16)	mov val1[1]=r0;						\
 (p16)	mov val1[0]=r0;						\
 	br.ctop.dptk 2b;					\
 	;;							\
diff -urN linux-2.4.20-pre6/arch/ia64/lib/do_csum.S linux-2.4.20-pre7/arch/ia64/lib/do_csum.S
--- linux-2.4.20-pre6/arch/ia64/lib/do_csum.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/do_csum.S	Thu Sep 12 20:01:39 2002
@@ -8,9 +8,14 @@
  *	in0: address of buffer to checksum (char *)
  *	in1: length of the buffer (int)
  *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
  *
+ * 02/04/22	Ken Chen <kenneth.w.chen@intel.com>
+ *		Data locality study on the checksum buffer.
+ *		More optimization cleanup - remove excessive stop bits.
+ * 02/04/08	David Mosberger <davidm@hpl.hp.com>
+ *		More cleanup and tuning.
  * 01/04/18	Jun Nakajima <jun.nakajima@intel.com>
  *		Clean up and optimize and the software pipeline, loading two
  *		back-to-back 8-byte words per loop. Clean up the initialization
@@ -71,8 +76,6 @@
 //	calculating the Internet checksum.
 //
 // NOT YET DONE:
-//	- use the lfetch instruction to augment the chances of the data being in
-//	  the cache when we need it.
 //	- Maybe another algorithm which would take care of the folding at the
 //	  end in a different manner
 //	- Work with people more knowledgeable than me on the network stack
@@ -80,6 +83,12 @@
 //	  type of packet or alignment we get. Like the ip_fast_csum() routine
 //	  where we know we have at least 20bytes worth of data to checksum.
 //	- Do a better job of handling small packets.
+//	- Note on prefetching: it was found that under various load, i.e. ftp read/write,
+//	  nfs read/write, the L1 cache hit rate is at 60% and L2 cache hit rate is at 99.8%
+//	  on the data that buffer points to (partly because the checksum is often preceded by
+//	  a copy_from_user()).  This finding indiate that lfetch will not be beneficial since
+//	  the data is already in the cache.
+//
 
 #define saved_pfs	r11
 #define hmask		r16
@@ -102,10 +111,6 @@
 #define buf		in0
 #define len		in1
 
-#ifndef CONFIG_IA64_LOAD_LATENCY
-#define CONFIG_IA64_LOAD_LATENCY	2
-#endif
-
 #define LOAD_LATENCY	2	// XXX fix me
 
 #if (LOAD_LATENCY != 1) && (LOAD_LATENCY != 2)
@@ -121,69 +126,70 @@
 GLOBAL_ENTRY(do_csum)
 	.prologue
 	.save ar.pfs, saved_pfs
-	alloc saved_pfs=ar.pfs,2,16,1,16
-	.rotr word1[4], word2[4],result1[4],result2[4]
-	.rotp p[PIPE_DEPTH]
+	alloc saved_pfs=ar.pfs,2,16,0,16
+	.rotr word1[4], word2[4],result1[LOAD_LATENCY+2],result2[LOAD_LATENCY+2]
+	.rotp p[PIPE_DEPTH], pC1[2], pC2[2]
 	mov ret0=r0		// in case we have zero length
 	cmp.lt p0,p6=r0,len	// check for zero length or negative (32bit len)
-	;;			// avoid WAW on CFM
-	mov tmp3=0x7		// a temporary mask/value
+	;;
 	add tmp1=buf,len	// last byte's address
-(p6)	br.ret.spnt.many rp	// return if true (hope we can avoid that)
+	.save pr, saved_pr
+	mov saved_pr=pr		// preserve predicates (rotation)
+(p6)	br.ret.spnt.many rp	// return if zero or negative length
 
-	and firstoff=7,buf	// how many bytes off for first1 element
-	tbit.nz p15,p0=buf,0	// is buf an odd address ?
 	mov hmask=-1		// intialize head mask
-	;;
-	andcm first1=buf,tmp3	// 8byte aligned down address of first1 element
+	tbit.nz p15,p0=buf,0	// is buf an odd address?
+	and first1=-8,buf	// 8-byte align down address of first1 element
+
+	and firstoff=7,buf	// how many bytes off for first1 element
 	mov tmask=-1		// initialize tail mask
-	adds tmp2=-1,tmp1	// last-1
+
 	;;
+	adds tmp2=-1,tmp1	// last-1
 	and lastoff=7,tmp1	// how many bytes off for last element
-	andcm last=tmp2,tmp3	// address of word containing last byte
-	.save pr, saved_pr
-	mov saved_pr=pr		// preserve predicates (rotation)
+	;;
+	sub tmp1=8,lastoff	// complement to lastoff
+	and last=-8,tmp2	// address of word containing last byte
 	;;
 	sub tmp3=last,first1	// tmp3=distance from first1 to last
+	.save ar.lc, saved_lc
+	mov saved_lc=ar.lc	// save lc
 	cmp.eq p8,p9=last,first1	// everything fits in one word ?
-	sub tmp1=8,lastoff	// complement to lastoff
-	ld8 firstval=[first1],8	// load,ahead of time, "first1" word
+
+	ld8 firstval=[first1],8	// load, ahead of time, "first1" word
+	and tmp1=7, tmp1	// make sure that if tmp1==8 -> tmp1=0
 	shl tmp2=firstoff,3	// number of bits
 	;;
-	and tmp1=7, tmp1	// make sure that if tmp1==8 -> tmp1=0
-(p9)	ld8 lastval=[last]	// load,ahead of time, "last" word, if needed
+(p9)	ld8 lastval=[last]	// load, ahead of time, "last" word, if needed
+	shl tmp1=tmp1,3		// number of bits
 (p9)	adds tmp3=-8,tmp3	// effectively loaded
 	;;
 (p8)	mov lastval=r0		// we don't need lastval if first1==last
-	shl tmp1=tmp1,3		// number of bits
 	shl hmask=hmask,tmp2	// build head mask, mask off [0,first1off[
-	;;
 	shr.u tmask=tmask,tmp1	// build tail mask, mask off ]8,lastoff]
-	.save ar.lc, saved_lc
-	mov saved_lc=ar.lc	// save lc
 	;;
 	.body
 #define count tmp3
 
 (p8)	and hmask=hmask,tmask	// apply tail mask to head mask if 1 word only
 (p9)	and word2[0]=lastval,tmask	// mask last it as appropriate
-	shr.u count=count,3	// we do 8 bytes per loop (count)
+	shr.u count=count,3	// how many 8-byte?
 	;;
 	// If count is odd, finish this 8-byte word so that we can
 	// load two back-to-back 8-byte words per loop thereafter.
-	tbit.nz p10,p11=count,0		// if (count is odd)
 	and word1[0]=firstval,hmask	// and mask it as appropriate
+	tbit.nz p10,p11=count,0		// if (count is odd)
 	;;
 (p8)	mov result1[0]=word1[0]
 (p9)	add result1[0]=word1[0],word2[0]
 	;;
 	cmp.ltu p6,p0=result1[0],word1[0]	// check the carry
+	cmp.eq.or.andcm p8,p0=0,count		// exit if zero 8-byte
 	;;
 (p6)	adds result1[0]=1,result1[0]
 (p8)	br.cond.dptk .do_csum_exit	// if (within an 8-byte word)
-	;;
 (p11)	br.cond.dptk .do_csum16		// if (count is even)
-	;;
+
 	// Here count is odd.
 	ld8 word1[1]=[first1],8		// load an 8-byte word
 	cmp.eq p9,p10=1,count		// if (count == 1)
@@ -194,58 +200,43 @@
 	cmp.ltu p6,p0=result1[0],word1[1]
 	;;
 (p6)	adds result1[0]=1,result1[0]
-	;;
 (p9)	br.cond.sptk .do_csum_exit	// if (count == 1) exit
 	// Fall through to caluculate the checksum, feeding result1[0] as
 	// the initial value in result1[0].
-	;;
 	//
 	// Calculate the checksum loading two 8-byte words per loop.
 	//
 .do_csum16:
-	mov saved_lc=ar.lc
+	add first2=8,first1
 	shr.u count=count,1	// we do 16 bytes per loop
 	;;
-	cmp.eq p9,p10=r0,count	// if (count == 0)
+	adds count=-1,count
+	mov carry1=r0
+	mov carry2=r0
 	brp.loop.imp 1f,2f
 	;;
-	adds count=-1,count
 	mov ar.ec=PIPE_DEPTH
-	;;
 	mov ar.lc=count	// set lc
-	;;
+	mov pr.rot=1<<16
 	// result1[0] must be initialized in advance.
 	mov result2[0]=r0
 	;;
-	mov pr.rot=1<<16
-	;;
-	mov carry1=r0
-	mov carry2=r0
-	;;
-	add first2=8,first1
-	;;
-(p9)	br.cond.sptk .do_csum_exit
-	;;
-	nop.m	0
-	nop.i	0
-	;;
 	.align 32
 1:
-(ELD_1)	cmp.ltu p31,p0=result1[LOAD_LATENCY],word1[LOAD_LATENCY+1]
-(p32)	adds carry1=1,carry1
-(ELD_1)	cmp.ltu p47,p0=result2[LOAD_LATENCY],word2[LOAD_LATENCY+1]
-(p48)	adds carry2=1,carry2
+(ELD_1)	cmp.ltu pC1[0],p0=result1[LOAD_LATENCY],word1[LOAD_LATENCY+1]
+(pC1[1])adds carry1=1,carry1
+(ELD_1)	cmp.ltu pC2[0],p0=result2[LOAD_LATENCY],word2[LOAD_LATENCY+1]
+(pC2[1])adds carry2=1,carry2
 (ELD)	add result1[LOAD_LATENCY-1]=result1[LOAD_LATENCY],word1[LOAD_LATENCY]
 (ELD)	add result2[LOAD_LATENCY-1]=result2[LOAD_LATENCY],word2[LOAD_LATENCY]
 2:
-(p16)	ld8 word1[0]=[first1],16
-(p16)	ld8 word2[0]=[first2],16
+(p[0])	ld8 word1[0]=[first1],16
+(p[0])	ld8 word2[0]=[first2],16
 	br.ctop.sptk 1b
 	;;
-	// Since len is a 32-bit value, carry cannot be larger than
-	// a 64-bit value.
-(p32)	adds carry1=1,carry1	// since we miss the last one
-(p48)	adds carry2=1,carry2
+	// Since len is a 32-bit value, carry cannot be larger than a 64-bit value.
+(pC1[1])adds carry1=1,carry1	// since we miss the last one
+(pC2[1])adds carry2=1,carry2
 	;;
 	add result1[LOAD_LATENCY+1]=result1[LOAD_LATENCY+1],carry1
 	add result2[LOAD_LATENCY+1]=result2[LOAD_LATENCY+1],carry2
@@ -263,18 +254,15 @@
 (p6)	adds result1[0]=1,result1[0]
 	;;
 .do_csum_exit:
-	movl tmp3=0xffffffff
-	;;
-	// XXX Fixme
 	//
 	// now fold 64 into 16 bits taking care of carry
 	// that's not very good because it has lots of sequentiality
 	//
-	and tmp1=result1[0],tmp3
+	mov tmp3=0xffff
+	zxt4 tmp1=result1[0]
 	shr.u tmp2=result1[0],32
 	;;
 	add result1[0]=tmp1,tmp2
-	shr.u tmp3=tmp3,16
 	;;
 	and tmp1=result1[0],tmp3
 	shr.u tmp2=result1[0],16
diff -urN linux-2.4.20-pre6/arch/ia64/lib/ip_fast_csum.S linux-2.4.20-pre7/arch/ia64/lib/ip_fast_csum.S
--- linux-2.4.20-pre6/arch/ia64/lib/ip_fast_csum.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/lib/ip_fast_csum.S	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,90 @@
+/*
+ * Optmized version of the ip_fast_csum() function
+ * Used for calculating IP header checksum
+ *
+ * Return: 16bit checksum, complemented
+ *
+ * Inputs:
+ *      in0: address of buffer to checksum (char *)
+ *      in1: length of the buffer (int)
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
+ */
+
+#include <asm/asmmacro.h>
+
+/*
+ * Since we know that most likely this function is called with buf aligned
+ * on 4-byte boundary and 20 bytes in length, we can execution rather quickly
+ * versus calling generic version of do_csum, which has lots of overhead in
+ * handling various alignments and sizes.  However, due to lack of constrains
+ * put on the function input argument, cases with alignment not on 4-byte or
+ * size not equal to 20 bytes will be handled by the generic do_csum function.
+ */
+
+#define in0	r32
+#define in1	r33
+#define ret0	r8
+
+GLOBAL_ENTRY(ip_fast_csum)
+	.prologue
+	.body
+	cmp.ne	p6,p7=5,in1	// size other than 20 byte?
+	and	r14=3,in0	// is it aligned on 4-byte?
+	add	r15=4,in0	// second source pointer
+	;;
+	cmp.ne.or.andcm p6,p7=r14,r0
+	;;
+(p7)	ld4	r20=[in0],8
+(p7)	ld4	r21=[r15],8
+(p6)	br.spnt	.generic
+	;;
+	ld4	r22=[in0],8
+	ld4	r23=[r15],8
+	;;
+	ld4	r24=[in0]
+	add	r20=r20,r21
+	add	r22=r22,r23
+	;;
+	add	r20=r20,r22
+	;;
+	add	r20=r20,r24
+	;;
+	shr.u	ret0=r20,16	// now need to add the carry
+	zxt2	r20=r20
+	;;
+	add	r20=ret0,r20
+	;;
+	shr.u	ret0=r20,16	// add carry again
+	zxt2	r20=r20
+	;;
+	add	r20=ret0,r20
+	;;
+	shr.u	ret0=r20,16
+	zxt2	r20=r20
+	;;
+	add	r20=ret0,r20
+	;;
+	andcm	ret0=-1,r20
+	.restore sp		// reset frame state
+	br.ret.sptk.many b0
+	;;
+
+.generic:
+	.prologue
+	.save ar.pfs, r35
+	alloc	r35=ar.pfs,2,2,2,0
+	.save rp, r34
+	mov	r34=b0
+	.body
+	dep.z	out1=in1,2,30
+	mov	out0=in0
+	;;
+	br.call.sptk.many b0=do_csum
+	;;
+	andcm	ret0=-1,ret0
+	mov	ar.pfs=r35
+	mov	b0=r34
+	br.ret.sptk.many b0
+END(ip_fast_csum)
diff -urN linux-2.4.20-pre6/arch/ia64/lib/memcpy_mck.S linux-2.4.20-pre7/arch/ia64/lib/memcpy_mck.S
--- linux-2.4.20-pre6/arch/ia64/lib/memcpy_mck.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/ia64/lib/memcpy_mck.S	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,675 @@
+/*
+ * Itanium 2-optimized version of memcpy and copy_user function
+ *
+ * Inputs:
+ * 	in0:	destination address
+ *	in1:	source address
+ *	in2:	number of bytes to copy
+ * Output:
+ * 	0 if success, or number of byte NOT copied if error occurred.
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
+ */
+#include <linux/config.h>
+#include <asm/asmmacro.h>
+#include <asm/page.h>
+
+#if __GNUC__ >= 3
+# define EK(y...)	EX(y)
+#else
+# define EK(y,x...)	x
+#endif
+
+GLOBAL_ENTRY(bcopy)
+	.regstk 3,0,0,0
+	mov r8=in0
+	mov in0=in1
+	;;
+	mov in1=r8
+	;;
+END(bcopy)
+
+/* McKinley specific optimization */
+
+#define retval		r8
+#define saved_pfs	r31
+#define saved_lc	r10
+#define saved_pr	r11
+#define saved_in0	r14
+#define saved_in1	r15
+#define saved_in2	r16
+
+#define src0		r2
+#define src1		r3
+#define dst0		r17
+#define dst1		r18
+#define cnt		r9
+
+/* r19-r30 are temp for each code section */
+#define PREFETCH_DIST	8
+#define src_pre_mem	r19
+#define dst_pre_mem	r20
+#define src_pre_l2	r21
+#define dst_pre_l2	r22
+#define t1		r23
+#define t2		r24
+#define t3		r25
+#define t4		r26
+#define t5		t1	// alias!
+#define t6		t2	// alias!
+#define t7		t3	// alias!
+#define n8		r27
+#define t9		t5	// alias!
+#define t10		t4	// alias!
+#define t11		t7	// alias!
+#define t12		t6	// alias!
+#define t14		t10	// alias!
+#define t13		r28
+#define t15		r29
+#define tmp		r30
+
+/* defines for long_copy block */
+#define	A	0
+#define B	(PREFETCH_DIST)
+#define C	(B + PREFETCH_DIST)
+#define D	(C + 1)
+#define N	(D + 1)
+#define Nrot	((N + 7) & ~7)
+
+/* alias */
+#define in0		r32
+#define in1		r33
+#define in2		r34
+
+GLOBAL_ENTRY(memcpy)
+	and	r28=0x7,in0
+	and	r29=0x7,in1
+	mov	f6=f0
+	br.cond.sptk .common_code
+	;;
+END(memcpy)
+GLOBAL_ENTRY(__copy_user)
+	.prologue
+// check dest alignment
+	and	r28=0x7,in0
+	and	r29=0x7,in1
+	mov	f6=f1
+	mov	saved_in0=in0	// save dest pointer
+	mov	saved_in1=in1	// save src pointer
+	mov	saved_in2=in2	// save len
+	;;
+.common_code:
+	cmp.gt	p15,p0=8,in2	// check for small size
+	cmp.ne	p13,p0=0,r28	// check dest alignment
+	cmp.ne	p14,p0=0,r29	// check src alignment
+	add	src0=0,in1
+	sub	r30=8,r28	// for .align_dest
+	mov	retval=r0	// initialize return value
+	;;
+	add	dst0=0,in0
+	add	dst1=1,in0	// dest odd index
+	cmp.le	p6,p0 = 1,r30	// for .align_dest
+(p15)	br.cond.dpnt .memcpy_short
+(p13)	br.cond.dpnt .align_dest
+(p14)	br.cond.dpnt .unaligned_src
+	;;
+
+// both dest and src are aligned on 8-byte boundary
+.aligned_src:
+	.save ar.pfs, saved_pfs
+	alloc	saved_pfs=ar.pfs,3,Nrot-3,0,Nrot
+	.save pr, saved_pr
+	mov	saved_pr=pr
+
+	shr.u	cnt=in2,7	// this much cache line
+	;;
+	cmp.lt	p6,p0=2*PREFETCH_DIST,cnt
+	cmp.lt	p7,p8=1,cnt
+	.save ar.lc, saved_lc
+	mov	saved_lc=ar.lc
+	.body
+	add	cnt=-1,cnt
+	add	src_pre_mem=0,in1	// prefetch src pointer
+	add	dst_pre_mem=0,in0	// prefetch dest pointer
+	;;
+(p7)	mov	ar.lc=cnt	// prefetch count
+(p8)	mov	ar.lc=r0
+(p6)	br.cond.dpnt .long_copy
+	;;
+
+.prefetch:
+	lfetch	  [src_pre_mem], 128
+	lfetch.excl [dst_pre_mem], 128
+	br.cloop.dptk.few .prefetch
+	;;
+
+.medium_copy:
+	and	tmp=31,in2	// copy length after iteration
+	shr.u	r29=in2,5	// number of 32-byte iteration
+	add	dst1=8,dst0	// 2nd dest pointer
+	;;
+	add	cnt=-1,r29	// ctop iteration adjustment
+	cmp.eq	p10,p0=r29,r0	// do we really need to loop?
+	add	src1=8,src0	// 2nd src pointer
+	cmp.le	p6,p0=8,tmp
+	;;
+	cmp.le	p7,p0=16,tmp
+	mov	ar.lc=cnt	// loop setup
+	cmp.eq	p16,p17 = r0,r0
+	mov	ar.ec=2
+(p10)	br.dpnt.few .aligned_src_tail
+	;;
+	.align 32
+1:
+EX(.ex_handler, (p16)	ld8	r34=[src0],16)
+EK(.ex_handler, (p16)	ld8	r38=[src1],16)
+EX(.ex_handler, (p17)	st8	[dst0]=r33,16)
+EK(.ex_handler, (p17)	st8	[dst1]=r37,16)
+	;;
+EX(.ex_handler, (p16)	ld8	r32=[src0],16)
+EK(.ex_handler, (p16)	ld8	r36=[src1],16)
+EX(.ex_handler, (p16)	st8	[dst0]=r34,16)
+EK(.ex_handler, (p16)	st8	[dst1]=r38,16)
+	br.ctop.dptk.few 1b
+	;;
+
+.aligned_src_tail:
+EX(.ex_handler, (p6)	ld8	t1=[src0])
+	mov	ar.lc=saved_lc
+	mov	ar.pfs=saved_pfs
+EX(.ex_hndlr_s, (p7)	ld8	t2=[src1],8)
+	cmp.le	p8,p0=24,tmp
+	and	r21=-8,tmp
+	;;
+EX(.ex_hndlr_s, (p8)	ld8	t3=[src1])
+EX(.ex_handler, (p6)	st8	[dst0]=t1)	// store byte 1
+	and	in2=7,tmp	// remaining length
+EX(.ex_hndlr_d, (p7)	st8	[dst1]=t2,8)	// store byte 2
+	add	src0=src0,r21	// setting up src pointer
+	add	dst0=dst0,r21	// setting up dest pointer
+	;;
+EX(.ex_handler, (p8)	st8	[dst1]=t3)	// store byte 3
+	mov	pr=saved_pr,-1
+	br.dptk.many .memcpy_short
+	;;
+
+/* code taken from copy_page_mck */
+.long_copy:
+	.rotr v[2*PREFETCH_DIST]
+	.rotp p[N]
+
+	mov src_pre_mem = src0
+	mov pr.rot = 0x10000
+	mov ar.ec = 1				// special unrolled loop
+
+	mov dst_pre_mem = dst0
+
+	add src_pre_l2 = 8*8, src0
+	add dst_pre_l2 = 8*8, dst0
+	;;
+	add src0 = 8, src_pre_mem		// first t1 src
+	mov ar.lc = 2*PREFETCH_DIST - 1
+	shr.u cnt=in2,7				// number of lines
+	add src1 = 3*8, src_pre_mem		// first t3 src
+	add dst0 = 8, dst_pre_mem		// first t1 dst
+	add dst1 = 3*8, dst_pre_mem		// first t3 dst
+	;;
+	and tmp=127,in2				// remaining bytes after this block
+	add cnt = -(2*PREFETCH_DIST) - 1, cnt
+	// same as .line_copy loop, but with all predicated-off instructions removed:
+.prefetch_loop:
+EX(.ex_hndlr_lcpy_1, (p[A])	ld8 v[A] = [src_pre_mem], 128)		// M0
+EK(.ex_hndlr_lcpy_1, (p[B])	st8 [dst_pre_mem] = v[B], 128)		// M2
+	br.ctop.sptk .prefetch_loop
+	;;
+	cmp.eq p16, p0 = r0, r0			// reset p16 to 1
+	mov ar.lc = cnt
+	mov ar.ec = N				// # of stages in pipeline
+	;;
+.line_copy:
+EX(.ex_handler,	(p[D])	ld8 t2 = [src0], 3*8)			// M0
+EK(.ex_handler,	(p[D])	ld8 t4 = [src1], 3*8)			// M1
+EX(.ex_handler_lcpy,	(p[B])	st8 [dst_pre_mem] = v[B], 128)		// M2 prefetch dst from memory
+EK(.ex_handler_lcpy,	(p[D])	st8 [dst_pre_l2] = n8, 128)		// M3 prefetch dst from L2
+	;;
+EX(.ex_handler_lcpy,	(p[A])	ld8 v[A] = [src_pre_mem], 128)		// M0 prefetch src from memory
+EK(.ex_handler_lcpy,	(p[C])	ld8 n8 = [src_pre_l2], 128)		// M1 prefetch src from L2
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t1, 8)			// M2
+EK(.ex_handler,	(p[D])	st8 [dst1] =  t3, 8)			// M3
+	;;
+EX(.ex_handler,	(p[D])	ld8  t5 = [src0], 8)
+EK(.ex_handler,	(p[D])	ld8  t7 = [src1], 3*8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t2, 3*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] =  t4, 3*8)
+	;;
+EX(.ex_handler,	(p[D])	ld8  t6 = [src0], 3*8)
+EK(.ex_handler,	(p[D])	ld8 t10 = [src1], 8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t5, 8)
+EK(.ex_handler,	(p[D])	st8 [dst1] =  t7, 3*8)
+	;;
+EX(.ex_handler,	(p[D])	ld8  t9 = [src0], 3*8)
+EK(.ex_handler,	(p[D])	ld8 t11 = [src1], 3*8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t6, 3*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t10, 8)
+	;;
+EX(.ex_handler,	(p[D])	ld8 t12 = [src0], 8)
+EK(.ex_handler,	(p[D])	ld8 t14 = [src1], 8)
+EX(.ex_handler,	(p[D])	st8 [dst0] =  t9, 3*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t11, 3*8)
+	;;
+EX(.ex_handler,	(p[D])	ld8 t13 = [src0], 4*8)
+EK(.ex_handler,	(p[D])	ld8 t15 = [src1], 4*8)
+EX(.ex_handler,	(p[D])	st8 [dst0] = t12, 8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t14, 8)
+	;;
+EX(.ex_handler,	(p[C])	ld8  t1 = [src0], 8)
+EK(.ex_handler,	(p[C])	ld8  t3 = [src1], 8)
+EX(.ex_handler,	(p[D])	st8 [dst0] = t13, 4*8)
+EK(.ex_handler,	(p[D])	st8 [dst1] = t15, 4*8)
+	br.ctop.sptk .line_copy
+	;;
+
+	add dst0=-8,dst0
+	add src0=-8,src0
+	mov in2=tmp
+	.restore sp
+	br.sptk.many .medium_copy
+	;;
+
+#define BLOCK_SIZE	128*32
+#define blocksize	r23
+#define curlen		r24
+
+// dest is on 8-byte boundary, src is not. We need to do
+// ld8-ld8, shrp, then st8.  Max 8 byte copy per cycle.
+.unaligned_src:
+	.prologue
+	.save ar.pfs, saved_pfs
+	alloc	saved_pfs=ar.pfs,3,5,0,8
+	.save ar.lc, saved_lc
+	mov	saved_lc=ar.lc
+	.save pr, saved_pr
+	mov	saved_pr=pr
+	.body
+.4k_block:
+	mov	saved_in0=dst0	// need to save all input arguments
+	mov	saved_in2=in2
+	mov	blocksize=BLOCK_SIZE
+	;;
+	cmp.lt	p6,p7=blocksize,in2
+	mov	saved_in1=src0
+	;;
+(p6)	mov	in2=blocksize
+	;;
+	shr.u	r21=in2,7	// this much cache line
+	shr.u	r22=in2,4	// number of 16-byte iteration
+	and	curlen=15,in2	// copy length after iteration
+	and	r30=7,src0	// source alignment
+	;;
+	cmp.lt	p7,p8=1,r21
+	add	cnt=-1,r21
+	;;
+
+	add	src_pre_mem=0,src0	// prefetch src pointer
+	add	dst_pre_mem=0,dst0	// prefetch dest pointer
+	and	src0=-8,src0		// 1st src pointer
+(p7)	mov	ar.lc = r21
+(p8)	mov	ar.lc = r0
+	;;
+	.align 32
+1:	lfetch	  [src_pre_mem], 128
+	lfetch.excl [dst_pre_mem], 128
+	br.cloop.dptk.few 1b
+	;;
+
+	shladd	dst1=r22,3,dst0	// 2nd dest pointer
+	shladd	src1=r22,3,src0	// 2nd src pointer
+	cmp.eq	p8,p9=r22,r0	// do we really need to loop?
+	cmp.le	p6,p7=8,curlen;	// have at least 8 byte remaining?
+	add	cnt=-1,r22	// ctop iteration adjustment
+	;;
+EX(.ex_handler, (p9)	ld8	r33=[src0],8)	// loop primer
+EK(.ex_handler, (p9)	ld8	r37=[src1],8)
+(p8)	br.dpnt.few .noloop
+	;;
+
+// The jump address is calculated based on src alignment. The COPYU
+// macro below need to confine its size to power of two, so an entry
+// can be caulated using shl instead of an expensive multiply. The
+// size is then hard coded by the following #define to match the
+// actual size.  This make it somewhat tedious when COPYU macro gets
+// changed and this need to be adjusted to match.
+#define LOOP_SIZE 6
+1:
+	mov	r29=ip		// jmp_table thread
+	mov	ar.lc=cnt
+	;;
+	add	r29=.jump_table - 1b - (.jmp1-.jump_table), r29
+	shl	r28=r30, LOOP_SIZE	// jmp_table thread
+	mov	ar.ec=2		// loop setup
+	;;
+	add	r29=r29,r28		// jmp_table thread
+	cmp.eq	p16,p17=r0,r0
+	;;
+	mov	b6=r29			// jmp_table thread
+	;;
+	br.cond.sptk.few b6
+
+// for 8-15 byte case
+// We will skip the loop, but need to replicate the side effect
+// that the loop produces.
+.noloop:
+EX(.ex_handler, (p6)	ld8	r37=[src1],8)
+	add	src0=8,src0
+(p6)	shl	r25=r30,3
+	;;
+EX(.ex_handler, (p6)	ld8	r27=[src1])
+(p6)	shr.u	r28=r37,r25
+(p6)	sub	r26=64,r25
+	;;
+(p6)	shl	r27=r27,r26
+	;;
+(p6)	or	r21=r28,r27
+
+.unaligned_src_tail:
+/* check if we have more than blocksize to copy, if so go back */
+	cmp.gt	p8,p0=saved_in2,blocksize
+	;;
+(p8)	add	dst0=saved_in0,blocksize
+(p8)	add	src0=saved_in1,blocksize
+(p8)	sub	in2=saved_in2,blocksize
+(p8)	br.dpnt	.4k_block
+	;;
+
+/* we have up to 15 byte to copy in the tail.
+ * part of work is already done in the jump table code
+ * we are at the following state.
+ * src side:
+ * 
+ *   xxxxxx xx                   <----- r21 has xxxxxxxx already
+ * -------- -------- --------
+ * 0        8        16
+ *          ^
+ *          |
+ *          src1
+ * 
+ * dst
+ * -------- -------- --------
+ * ^
+ * |
+ * dst1
+ */
+EX(.ex_handler, (p6)	st8	[dst1]=r21,8)	// more than 8 byte to copy
+(p6)	add	curlen=-8,curlen	// update length
+	mov	ar.pfs=saved_pfs
+	;;
+	mov	ar.lc=saved_lc
+	mov	pr=saved_pr,-1
+	mov	in2=curlen	// remaining length
+	mov	dst0=dst1	// dest pointer
+	add	src0=src1,r30	// forward by src alignment
+	;;
+
+// 7 byte or smaller.
+.memcpy_short:
+	cmp.le	p8,p9   = 1,in2
+	cmp.le	p10,p11 = 2,in2
+	cmp.le	p12,p13 = 3,in2
+	cmp.le	p14,p15 = 4,in2
+	add	src1=1,src0	// second src pointer
+	add	dst1=1,dst0	// second dest pointer
+	;;
+
+EX(.ex_handler_short, (p8)	ld1	t1=[src0],2)
+EK(.ex_handler_short, (p10)	ld1	t2=[src1],2)
+(p9)	br.ret.dpnt rp		// 0 byte copy
+	;;
+
+EX(.ex_handler_short, (p8)	st1	[dst0]=t1,2)
+EK(.ex_handler_short, (p10)	st1	[dst1]=t2,2)
+(p11)	br.ret.dpnt rp		// 1 byte copy
+
+EX(.ex_handler_short, (p12)	ld1	t3=[src0],2)
+EK(.ex_handler_short, (p14)	ld1	t4=[src1],2)
+(p13)	br.ret.dpnt rp		// 2 byte copy
+	;;
+
+	cmp.le	p6,p7   = 5,in2
+	cmp.le	p8,p9   = 6,in2
+	cmp.le	p10,p11 = 7,in2
+
+EX(.ex_handler_short, (p12)	st1	[dst0]=t3,2)
+EK(.ex_handler_short, (p14)	st1	[dst1]=t4,2)
+(p15)	br.ret.dpnt rp		// 3 byte copy
+	;;
+
+EX(.ex_handler_short, (p6)	ld1	t5=[src0],2)
+EK(.ex_handler_short, (p8)	ld1	t6=[src1],2)
+(p7)	br.ret.dpnt rp		// 4 byte copy
+	;;
+
+EX(.ex_handler_short, (p6)	st1	[dst0]=t5,2)
+EK(.ex_handler_short, (p8)	st1	[dst1]=t6,2)
+(p9)	br.ret.dptk rp		// 5 byte copy
+
+EX(.ex_handler_short, (p10)	ld1	t7=[src0],2)
+(p11)	br.ret.dptk rp		// 6 byte copy
+	;;
+
+EX(.ex_handler_short, (p10)	st1	[dst0]=t7,2)
+	br.ret.dptk rp		// done all cases
+
+
+/* Align dest to nearest 8-byte boundary. We know we have at
+ * least 7 bytes to copy, enough to crawl to 8-byte boundary.
+ * Actual number of byte to crawl depend on the dest alignment.
+ * 7 byte or less is taken care at .memcpy_short
+
+ * src0 - source even index
+ * src1 - source  odd index
+ * dst0 - dest even index
+ * dst1 - dest  odd index
+ * r30  - distance to 8-byte boundary
+ */
+
+.align_dest:
+	add	src1=1,in1	// source odd index
+	cmp.le	p7,p0 = 2,r30	// for .align_dest
+	cmp.le	p8,p0 = 3,r30	// for .align_dest
+EX(.ex_handler_short, (p6)	ld1	t1=[src0],2)
+	cmp.le	p9,p0 = 4,r30	// for .align_dest
+	cmp.le	p10,p0 = 5,r30
+	;;
+EX(.ex_handler_short, (p7)	ld1	t2=[src1],2)
+EK(.ex_handler_short, (p8)	ld1	t3=[src0],2)
+	cmp.le	p11,p0 = 6,r30
+EX(.ex_handler_short, (p6)	st1	[dst0] = t1,2)
+	cmp.le	p12,p0 = 7,r30
+	;;
+EX(.ex_handler_short, (p9)	ld1	t4=[src1],2)
+EK(.ex_handler_short, (p10)	ld1	t5=[src0],2)
+EX(.ex_handler_short, (p7)	st1	[dst1] = t2,2)
+EK(.ex_handler_short, (p8)	st1	[dst0] = t3,2)
+	;;
+EX(.ex_handler_short, (p11)	ld1	t6=[src1],2)
+EK(.ex_handler_short, (p12)	ld1	t7=[src0],2)
+	cmp.eq	p6,p7=r28,r29
+EX(.ex_handler_short, (p9)	st1	[dst1] = t4,2)
+EK(.ex_handler_short, (p10)	st1	[dst0] = t5,2)
+	sub	in2=in2,r30
+	;;
+EX(.ex_handler_short, (p11)	st1	[dst1] = t6,2)
+EK(.ex_handler_short, (p12)	st1	[dst0] = t7)
+	add	dst0=in0,r30	// setup arguments
+	add	src0=in1,r30
+(p6)	br.cond.dptk .aligned_src
+(p7)	br.cond.dpnt .unaligned_src
+	;;
+
+/* main loop body in jump table format */
+#define COPYU(shift)									\
+1:											\
+EX(.ex_handler,  (p16)	ld8	r32=[src0],8);		/* 1 */				\
+EK(.ex_handler,  (p16)	ld8	r36=[src1],8);						\
+		 (p17)	shrp	r35=r33,r34,shift;;	/* 1 */				\
+EX(.ex_handler,  (p6)	ld8	r22=[src1]);	/* common, prime for tail section */	\
+		 nop.m	0;								\
+		 (p16)	shrp	r38=r36,r37,shift;					\
+EX(.ex_handler,  (p17)	st8	[dst0]=r35,8);		/* 1 */				\
+EK(.ex_handler,  (p17)	st8	[dst1]=r39,8);						\
+		 br.ctop.dptk.few 1b;;							\
+		 (p7)	add	src1=-8,src1;	/* back out for <8 byte case */		\
+		 shrp	r21=r22,r38,shift;	/* speculative work */			\
+		 br.sptk.few .unaligned_src_tail /* branch out of jump table */		\
+		 ;;
+	.align 32
+.jump_table:
+	COPYU(8)	// unaligned cases
+.jmp1:
+	COPYU(16)
+	COPYU(24)
+	COPYU(32)
+	COPYU(40)
+	COPYU(48)
+	COPYU(56)
+
+#undef A
+#undef B
+#undef C
+#undef D
+END(memcpy)
+
+/*
+ * Due to lack of local tag support in gcc 2.x assembler, it is not clear which
+ * instruction failed in the bundle.  The exception algorithm is that we
+ * first figure out the faulting address, then detect if there is any
+ * progress made on the copy, if so, redo the copy from last known copied
+ * location up to the faulting address (exclusive). In the copy_from_user
+ * case, remaining byte in kernel buffer will be zeroed.
+ *
+ * Take copy_from_user as an example, in the code there are multiple loads
+ * in a bundle and those multiple loads could span over two pages, the
+ * faulting address is calculated as page_round_down(max(src0, src1)).
+ * This is based on knowledge that if we can access one byte in a page, we
+ * can access any byte in that page.
+ *
+ * predicate used in the exception handler:
+ * p6-p7: direction
+ * p10-p11: src faulting addr calculation
+ * p12-p13: dst faulting addr calculation
+ */
+
+#define A	r19
+#define B	r20
+#define C	r21
+#define D	r22
+#define F	r28
+
+#define memset_arg0	r32
+#define memset_arg2	r33
+
+#define saved_retval	loc0
+#define saved_rtlink	loc1
+#define saved_pfs_stack	loc2
+
+.ex_hndlr_s:
+	add	src0=8,src0
+	br.sptk .ex_handler
+	;;
+.ex_hndlr_d:
+	add	dst0=8,dst0
+	br.sptk .ex_handler
+	;;
+.ex_hndlr_lcpy_1:
+	mov	src1=src_pre_mem
+	mov	dst1=dst_pre_mem
+	cmp.gtu	p10,p11=src_pre_mem,saved_in1
+	cmp.gtu	p12,p13=dst_pre_mem,saved_in0
+	;;
+(p10)	add	src0=8,saved_in1
+(p11)	mov	src0=saved_in1
+(p12)	add	dst0=8,saved_in0
+(p13)	mov	dst0=saved_in0
+	br.sptk	.ex_handler
+.ex_handler_lcpy:
+	// in line_copy block, the preload addresses should always ahead
+	// of the other two src/dst pointers.  Furthermore, src1/dst1 should
+	// always ahead of src0/dst0.
+	mov	src1=src_pre_mem
+	mov	dst1=dst_pre_mem
+.ex_handler:
+	mov	pr=saved_pr,-1		// first restore pr, lc, and pfs
+	mov	ar.lc=saved_lc
+	mov	ar.pfs=saved_pfs
+	;;
+.ex_handler_short: // fault occurred in these sections didn't change pr, lc, pfs
+	cmp.ltu	p6,p7=saved_in0, saved_in1	// get the copy direction
+	cmp.ltu	p10,p11=src0,src1
+	cmp.ltu	p12,p13=dst0,dst1
+	fcmp.eq	p8,p0=f6,f0		// is it memcpy?
+	mov	tmp = dst0
+	;;
+(p11)	mov	src1 = src0		// pick the larger of the two
+(p13)	mov	dst0 = dst1		// make dst0 the smaller one
+(p13)	mov	dst1 = tmp		// and dst1 the larger one
+	;;
+(p6)	dep	F = r0,dst1,0,PAGE_SHIFT // usr dst round down to page boundary
+(p7)	dep	F = r0,src1,0,PAGE_SHIFT // usr src round down to page boundary
+	;;
+(p6)	cmp.le	p14,p0=dst0,saved_in0	// no progress has been made on store
+(p7)	cmp.le	p14,p0=src0,saved_in1	// no progress has been made on load
+	mov	retval=saved_in2
+(p8)	ld1	tmp=[src1]		// force an oops for memcpy call
+(p8)	st1	[dst1]=r0		// force an oops for memcpy call
+(p14)	br.ret.sptk.many rp
+
+/*
+ * The remaining byte to copy is calculated as:
+ *
+ * A =	(faulting_addr - orig_src)	-> len to faulting ld address
+ *	or 
+ * 	(faulting_addr - orig_dst)	-> len to faulting st address
+ * B =	(cur_dst - orig_dst)		-> len copied so far
+ * C =	A - B				-> len need to be copied
+ * D =	orig_len - A			-> len need to be zeroed
+ */
+(p6)	sub	A = F, saved_in0
+(p7)	sub	A = F, saved_in1
+	clrrrb
+	;;
+	alloc	saved_pfs_stack=ar.pfs,3,3,3,0
+	sub	B = dst0, saved_in0	// how many byte copied so far
+	;;
+	sub	C = A, B
+	sub	D = saved_in2, A
+	;;
+	cmp.gt	p8,p0=C,r0		// more than 1 byte?
+	add	memset_arg0=saved_in0, A
+(p6)	mov	memset_arg2=0		// copy_to_user should not call memset
+(p7)	mov	memset_arg2=D		// copy_from_user need to have kbuf zeroed
+	mov	r8=0
+	mov	saved_retval = D
+	mov	saved_rtlink = b0
+
+	add	out0=saved_in0, B
+	add	out1=saved_in1, B
+	mov	out2=C
+(p8)	br.call.sptk.few b0=__copy_user	// recursive call
+	;;
+
+	add	saved_retval=saved_retval,r8	// above might return non-zero value
+	cmp.gt	p8,p0=memset_arg2,r0	// more than 1 byte?
+	mov	out0=memset_arg0	// *s
+	mov	out1=r0			// c
+	mov	out2=memset_arg2	// n
+(p8)	br.call.sptk.few b0=memset
+	;;
+
+	mov	retval=saved_retval
+	mov	ar.pfs=saved_pfs_stack
+	mov	b0=saved_rtlink
+	br.ret.sptk.many rp
+
+/* end of McKinley specific optimization */
+END(__copy_user)
diff -urN linux-2.4.20-pre6/arch/ia64/lib/memset.S linux-2.4.20-pre7/arch/ia64/lib/memset.S
--- linux-2.4.20-pre6/arch/ia64/lib/memset.S	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/lib/memset.S	Thu Sep 12 20:01:39 2002
@@ -1,108 +1,362 @@
-/*
- *
- * Optimized version of the standard memset() function
- *
- * Return: none
- *
- * Inputs:
- *	in0:	address of buffer
- * 	in1:	byte value to use for storing
- *	in2:	length of the buffer
- *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- */
+/* Optimized version of the standard memset() function.
+
+   Copyright (c) 2002 Hewlett-Packard Co/CERN
+	Sverre Jarp <Sverre.Jarp@cern.ch>
+
+   Return: dest
+
+   Inputs:
+        in0:    dest
+        in1:    value
+        in2:    count
+
+   The algorithm is fairly straightforward: set byte by byte until we
+   we get to a 16B-aligned address, then loop on 128 B chunks using an
+   early store as prefetching, then loop on 32B chucks, then clear remaining
+   words, finally clear remaining bytes.
+   Since a stf.spill f0 can store 16B in one go, we use this instruction
+   to get peak speed when value = 0.  */
 
 #include <asm/asmmacro.h>
+#undef ret
+
+#define dest		in0
+#define value		in1
+#define	cnt		in2
 
-// arguments
-//
-#define buf		r32
-#define val		r33
-#define len		r34
-
-//
-// local registers
-//
-#define saved_pfs	r14
-#define cnt		r18
-#define buf2		r19
-#define saved_lc	r20
-#define tmp		r21
+#define tmp		r31
+#define save_lc		r30
+#define ptr0		r29
+#define ptr1		r28
+#define ptr2		r27
+#define ptr3		r26
+#define ptr9 		r24
+#define	loopcnt		r23
+#define linecnt		r22
+#define bytecnt		r21
+
+#define fvalue		f6
+
+// This routine uses only scratch predicate registers (p6 - p15)
+#define p_scr		p6			// default register for same-cycle branches
+#define p_nz		p7
+#define p_zr		p8
+#define p_unalgn	p9
+#define p_y		p11
+#define p_n		p12
+#define p_yy		p13
+#define p_nn		p14
+
+#define MIN1		15
+#define MIN1P1HALF	8
+#define LINE_SIZE	128
+#define LSIZE_SH        7			// shift amount
+#define PREF_AHEAD	8
 
 GLOBAL_ENTRY(memset)
+{ .mmi
 	.prologue
-	.save ar.pfs, saved_pfs
- 	alloc saved_pfs=ar.pfs,3,0,0,0	// cnt is sink here
-	cmp.eq p8,p0=r0,len	// check for zero length
-	.save ar.lc, saved_lc
-	mov saved_lc=ar.lc	// preserve ar.lc (slow)
-	;;
-
+	alloc	tmp = ar.pfs, 3, 0, 0, 0
 	.body
+	lfetch.nt1 [dest]			//
+	.save   ar.lc, save_lc
+	mov.i	save_lc = ar.lc
+} { .mmi
+	mov	ret0 = dest			// return value
+	cmp.ne	p_nz, p_zr = value, r0		// use stf.spill if value is zero
+	cmp.eq	p_scr, p0 = cnt, r0
+;; }
+{ .mmi
+	and	ptr2 = -(MIN1+1), dest		// aligned address
+	and	tmp = MIN1, dest		// prepare to check for correct alignment
+	tbit.nz p_y, p_n = dest, 0		// Do we have an odd address? (M_B_U)
+} { .mib
+	mov	ptr1 = dest
+	mux1	value = value, @brcst		// create 8 identical bytes in word
+(p_scr)	br.ret.dpnt.many rp			// return immediately if count = 0
+;; }
+{ .mib
+	cmp.ne	p_unalgn, p0 = tmp, r0		//
+} { .mib
+	sub	bytecnt = (MIN1+1), tmp		// NB: # of bytes to move is 1 higher than loopcnt
+	cmp.gt	p_scr, p0 = 16, cnt		// is it a minimalistic task?
+(p_scr)	br.cond.dptk.many .move_bytes_unaligned	// go move just a few (M_B_U)
+;; }
+{ .mmi
+(p_unalgn) add	ptr1 = (MIN1+1), ptr2		// after alignment
+(p_unalgn) add	ptr2 = MIN1P1HALF, ptr2		// after alignment
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3	// should we do a st8 ?
+;; }
+{ .mib
+(p_y)	add	cnt = -8, cnt			//
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2	// should we do a st4 ?
+} { .mib
+(p_y)	st8	[ptr2] = value,-4		//
+(p_n)	add	ptr2 = 4, ptr2			//
+;; }
+{ .mib
+(p_yy)	add	cnt = -4, cnt			//
+(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1	// should we do a st2 ?
+} { .mib
+(p_yy)	st4	[ptr2] = value,-2		//
+(p_nn)	add	ptr2 = 2, ptr2			//
+;; }
+{ .mmi
+	mov	tmp = LINE_SIZE+1		// for compare
+(p_y)	add	cnt = -2, cnt			//
+(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0	// should we do a st1 ?
+} { .mmi
+	setf.sig fvalue=value			// transfer value to FLP side
+(p_y)	st2	[ptr2] = value,-1		//
+(p_n)	add	ptr2 = 1, ptr2			//
+;; }
+
+{ .mmi
+(p_yy)	st1	[ptr2] = value 			//
+  	cmp.gt	p_scr, p0 = tmp, cnt		// is it a minimalistic task?
+} { .mbb
+(p_yy)	add	cnt = -1, cnt			//
+(p_scr)	br.cond.dpnt.many .fraction_of_line	// go move just a few
+;; }
+
+{ .mib
+	nop.m 0
+	shr.u	linecnt = cnt, LSIZE_SH
+(p_zr)	br.cond.dptk.many .l1b			// Jump to use stf.spill
+;; }
+
+	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
+{ .mmi
+	and	tmp = -(LINE_SIZE), cnt		// compute end of range
+	mov	ptr9 = ptr1			// used for prefetching
+	and	cnt = (LINE_SIZE-1), cnt	// remainder
+} { .mmi
+	mov	loopcnt = PREF_AHEAD-1		// default prefetch loop
+	cmp.gt	p_scr, p0 = PREF_AHEAD, linecnt	// check against actual value
+;; }
+{ .mmi
+(p_scr)	add	loopcnt = -1, linecnt		//
+	add	ptr2 = 8, ptr1			// start of stores (beyond prefetch stores)
+	add	ptr1 = tmp, ptr1		// first address beyond total range
+;; }
+{ .mmi
+	add	tmp = -1, linecnt		// next loop count
+	mov.i	ar.lc = loopcnt			//
+;; }
+.pref_l1a:
+{ .mib
+	stf8 [ptr9] = fvalue, 128		// Do stores one cache line apart
+	nop.i	0
+	br.cloop.dptk.few .pref_l1a
+;; }
+{ .mmi
+	add	ptr0 = 16, ptr2			// Two stores in parallel
+	mov.i	ar.lc = tmp			//
+;; }
+.l1ax:
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 8
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 24
+	stf8 [ptr0] = fvalue, 24
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 8
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 24
+	stf8 [ptr0] = fvalue, 24
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 8
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 24
+	stf8 [ptr0] = fvalue, 24
+ ;; }
+ { .mmi
+	stf8 [ptr2] = fvalue, 8
+	stf8 [ptr0] = fvalue, 32
+ 	cmp.lt	p_scr, p0 = ptr9, ptr1		// do we need more prefetching?
+ ;; }
+{ .mmb
+	stf8 [ptr2] = fvalue, 24
+(p_scr)	stf8 [ptr9] = fvalue, 128
+	br.cloop.dptk.few .l1ax
+;; }
+{ .mbb
+	cmp.le  p_scr, p0 = 8, cnt		// just a few bytes left ?
+(p_scr) br.cond.dpnt.many  .fraction_of_line	// Branch no. 2
+	br.cond.dpnt.many  .move_bytes_from_alignment	// Branch no. 3
+;; }
+
+	.align 32
+.l1b:	// ------------------------------------ //  L1B: store ahead into cache lines; fill later
+{ .mmi
+	and	tmp = -(LINE_SIZE), cnt		// compute end of range
+	mov	ptr9 = ptr1			// used for prefetching
+	and	cnt = (LINE_SIZE-1), cnt	// remainder
+} { .mmi
+	mov	loopcnt = PREF_AHEAD-1		// default prefetch loop
+	cmp.gt	p_scr, p0 = PREF_AHEAD, linecnt	// check against actual value
+;; }
+{ .mmi
+(p_scr)	add	loopcnt = -1, linecnt
+	add	ptr2 = 16, ptr1			// start of stores (beyond prefetch stores)
+	add	ptr1 = tmp, ptr1		// first address beyond total range
+;; }
+{ .mmi
+	add	tmp = -1, linecnt		// next loop count
+	mov.i	ar.lc = loopcnt
+;; }
+.pref_l1b:
+{ .mib
+	stf.spill [ptr9] = f0, 128		// Do stores one cache line apart
+	nop.i   0
+	br.cloop.dptk.few .pref_l1b
+;; }
+{ .mmi
+	add	ptr0 = 16, ptr2			// Two stores in parallel
+	mov.i	ar.lc = tmp
+;; }
+.l1bx:
+ { .mmi
+	stf.spill [ptr2] = f0, 32
+	stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+	stf.spill [ptr2] = f0, 32
+	stf.spill [ptr0] = f0, 32
+ ;; }
+ { .mmi
+	stf.spill [ptr2] = f0, 32
+	stf.spill [ptr0] = f0, 64
+ 	cmp.lt	p_scr, p0 = ptr9, ptr1		// do we need more prefetching?
+ ;; }
+{ .mmb
+	stf.spill [ptr2] = f0, 32
+(p_scr)	stf.spill [ptr9] = f0, 128
+	br.cloop.dptk.few .l1bx
+;; }
+{ .mib
+	cmp.gt  p_scr, p0 = 8, cnt		// just a few bytes left ?
+(p_scr)	br.cond.dpnt.many  .move_bytes_from_alignment	//
+;; }
+
+.fraction_of_line:
+{ .mib
+	add	ptr2 = 16, ptr1
+	shr.u	loopcnt = cnt, 5   		// loopcnt = cnt / 32
+;; }
+{ .mib
+	cmp.eq	p_scr, p0 = loopcnt, r0
+	add	loopcnt = -1, loopcnt
+(p_scr)	br.cond.dpnt.many .store_words
+;; }
+{ .mib
+	and	cnt = 0x1f, cnt			// compute the remaining cnt
+	mov.i   ar.lc = loopcnt
+;; }
+	.align 32
+.l2:	// ------------------------------------ //  L2A:  store 32B in 2 cycles
+{ .mmb
+	stf8	[ptr1] = fvalue, 8
+	stf8	[ptr2] = fvalue, 8
+;; } { .mmb
+	stf8	[ptr1] = fvalue, 24
+	stf8	[ptr2] = fvalue, 24
+	br.cloop.dptk.many .l2
+;; }
+.store_words:
+{ .mib
+	cmp.gt	p_scr, p0 = 8, cnt		// just a few bytes left ?
+(p_scr)	br.cond.dpnt.many .move_bytes_from_alignment	// Branch
+;; }
+
+{ .mmi
+	stf8	[ptr1] = fvalue, 8		// store
+	cmp.le	p_y, p_n = 16, cnt
+	add	cnt = -8, cnt			// subtract
+;; }
+{ .mmi
+(p_y)	stf8	[ptr1] = fvalue, 8		// store
+(p_y)	cmp.le.unc p_yy, p_nn = 16, cnt
+(p_y)	add	cnt = -8, cnt			// subtract
+;; }
+{ .mmi						// store
+(p_yy)	stf8	[ptr1] = fvalue, 8
+(p_yy)	add	cnt = -8, cnt			// subtract
+;; }
+
+.move_bytes_from_alignment:
+{ .mib
+	cmp.eq	p_scr, p0 = cnt, r0
+	tbit.nz.unc p_y, p0 = cnt, 2		// should we terminate with a st4 ?
+(p_scr)	br.cond.dpnt.few .restore_and_exit
+;; }
+{ .mib
+(p_y)	st4	[ptr1] = value,4
+	tbit.nz.unc p_yy, p0 = cnt, 1		// should we terminate with a st2 ?
+;; }
+{ .mib
+(p_yy)	st2	[ptr1] = value,2
+	tbit.nz.unc p_y, p0 = cnt, 0		// should we terminate with a st1 ?
+;; }
+
+{ .mib
+(p_y)	st1	[ptr1] = value
+;; }
+.restore_and_exit:
+{ .mib
+	nop.m	0
+	mov.i	ar.lc = save_lc
+	br.ret.sptk.many rp
+;; }
 
-	adds tmp=-1,len		// br.ctop is repeat/until
-	tbit.nz p6,p0=buf,0	// odd alignment
-(p8)	br.ret.spnt.many rp
-
-	cmp.lt p7,p0=16,len	// if len > 16 then long memset
-	mux1 val=val,@brcst	// prepare value
-(p7)	br.cond.dptk .long_memset
-	;;
-	mov ar.lc=tmp		// initialize lc for small count
-	;;			// avoid RAW and WAW on ar.lc
-1:				// worst case 15 cyles, avg 8 cycles
-	st1 [buf]=val,1
-	br.cloop.dptk.few 1b
-	;;				// avoid RAW on ar.lc
-	mov ar.lc=saved_lc
-	mov ar.pfs=saved_pfs
-	br.ret.sptk.many rp	// end of short memset
-
-	// at this point we know we have more than 16 bytes to copy
-	// so we focus on alignment
-.long_memset:
-(p6)	st1 [buf]=val,1		// 1-byte aligned
-(p6)	adds len=-1,len;;	// sync because buf is modified
-	tbit.nz p6,p0=buf,1
-	;;
-(p6)	st2 [buf]=val,2		// 2-byte aligned
-(p6)	adds len=-2,len;;
-	tbit.nz p6,p0=buf,2
-	;;
-(p6)	st4 [buf]=val,4		// 4-byte aligned
-(p6)	adds len=-4,len;;
-	tbit.nz p6,p0=buf,3
-	;;
-(p6)	st8 [buf]=val,8		// 8-byte aligned
-(p6)	adds len=-8,len;;
-	shr.u cnt=len,4		// number of 128-bit (2x64bit) words
-	;;
-	cmp.eq p6,p0=r0,cnt
-	adds tmp=-1,cnt
-(p6)	br.cond.dpnt .dotail	// we have less than 16 bytes left
-	;;
-	adds buf2=8,buf		// setup second base pointer
-	mov ar.lc=tmp
-	;;
-2:				// 16bytes/iteration
-	st8 [buf]=val,16
-	st8 [buf2]=val,16
-	br.cloop.dptk.few 2b
-	;;
-.dotail:			// tail correction based on len only
-	tbit.nz p6,p0=len,3
-	;;
-(p6)	st8 [buf]=val,8		// at least 8 bytes
-	tbit.nz p6,p0=len,2
-	;;
-(p6)	st4 [buf]=val,4		// at least 4 bytes
-	tbit.nz p6,p0=len,1
-	;;
-(p6)	st2 [buf]=val,2		// at least 2 bytes
-	tbit.nz p6,p0=len,0
-	mov ar.lc=saved_lc
-	;;
-(p6)	st1 [buf]=val		// only 1 byte left
+.move_bytes_unaligned:
+{ .mmi
+       .pred.rel "mutex",p_y, p_n
+       .pred.rel "mutex",p_yy, p_nn
+(p_n)	cmp.le  p_yy, p_nn = 4, cnt
+(p_y)	cmp.le  p_yy, p_nn = 5, cnt
+(p_n)	add	ptr2 = 2, ptr1
+} { .mmi
+(p_y)	add	ptr2 = 3, ptr1
+(p_y)	st1	[ptr1] = value, 1		// fill 1 (odd-aligned) byte [15, 14 (or less) left]
+(p_y)	add	cnt = -1, cnt
+;; }
+{ .mmi
+(p_yy)	cmp.le.unc p_y, p0 = 8, cnt
+	add	ptr3 = ptr1, cnt		// prepare last store
+	mov.i	ar.lc = save_lc
+} { .mmi
+(p_yy)	st2	[ptr1] = value, 4		// fill 2 (aligned) bytes
+(p_yy)	st2	[ptr2] = value, 4		// fill 2 (aligned) bytes [11, 10 (o less) left]
+(p_yy)	add	cnt = -4, cnt
+;; }
+{ .mmi
+(p_y)	cmp.le.unc p_yy, p0 = 8, cnt
+	add	ptr3 = -1, ptr3			// last store
+	tbit.nz p_scr, p0 = cnt, 1		// will there be a st2 at the end ?
+} { .mmi
+(p_y)	st2	[ptr1] = value, 4		// fill 2 (aligned) bytes
+(p_y)	st2	[ptr2] = value, 4		// fill 2 (aligned) bytes [7, 6 (or less) left]
+(p_y)	add	cnt = -4, cnt
+;; }
+{ .mmi
+(p_yy)	st2	[ptr1] = value, 4		// fill 2 (aligned) bytes
+(p_yy)	st2	[ptr2] = value, 4		// fill 2 (aligned) bytes [3, 2 (or less) left]
+	tbit.nz p_y, p0 = cnt, 0		// will there be a st1 at the end ?
+} { .mmi
+(p_yy)	add	cnt = -4, cnt
+;; }
+{ .mmb
+(p_scr)	st2	[ptr1] = value			// fill 2 (aligned) bytes
+(p_y)	st1	[ptr3] = value			// fill last byte (using ptr3)
 	br.ret.sptk.many rp
+}
 END(memset)
diff -urN linux-2.4.20-pre6/arch/ia64/lib/swiotlb.c linux-2.4.20-pre7/arch/ia64/lib/swiotlb.c
--- linux-2.4.20-pre6/arch/ia64/lib/swiotlb.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/lib/swiotlb.c	Thu Sep 12 20:01:39 2002
@@ -277,8 +277,11 @@
 	int gfp = GFP_ATOMIC;
 	void *ret;
 
-	if (!hwdev || hwdev->dma_mask <= 0xffffffff)
-		gfp |= GFP_DMA; /* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */
+	/*
+	 * Alloc_consistent() is defined to return memory < 4GB, no matter what the DMA
+	 * mask says.
+	 */
+	gfp |= GFP_DMA;	/* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 	if (!ret)
 		return NULL;
@@ -486,6 +489,17 @@
 	return SG_ENT_PHYS_ADDRESS(sg);
 }
 
+/*
+ * 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.
+ */
+int
+swiotlb_pci_dma_supported (struct pci_dev *hwdev, u64 mask)
+{
+	return 1;
+}
+
 EXPORT_SYMBOL(swiotlb_init);
 EXPORT_SYMBOL(swiotlb_map_single);
 EXPORT_SYMBOL(swiotlb_unmap_single);
@@ -496,3 +510,4 @@
 EXPORT_SYMBOL(swiotlb_dma_address);
 EXPORT_SYMBOL(swiotlb_alloc_consistent);
 EXPORT_SYMBOL(swiotlb_free_consistent);
+EXPORT_SYMBOL(swiotlb_pci_dma_supported);
diff -urN linux-2.4.20-pre6/arch/ia64/mm/fault.c linux-2.4.20-pre7/arch/ia64/mm/fault.c
--- linux-2.4.20-pre6/arch/ia64/mm/fault.c	Thu Sep 12 20:01:29 2002
+++ linux-2.4.20-pre7/arch/ia64/mm/fault.c	Thu Sep 12 20:01:39 2002
@@ -49,7 +49,6 @@
 	int signal = SIGSEGV, code = SEGV_MAPERR;
 	struct vm_area_struct *vma, *prev_vma;
 	struct mm_struct *mm = current->mm;
-	struct exception_fixup fix;
 	struct siginfo si;
 	unsigned long mask;
 
@@ -59,6 +58,17 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+	/*
+	 * If fault is in region 5 and we are in the kernel, we may already
+         * have the mmap_sem (VALID_PAGE macro is called during mmap). There
+	 * should be no vma for region 5 addr's anyway, so skip getting the
+	 * semaphore and go directly to the code that handles a bad area.
+  	 */
+	if ((REGION_NUMBER(address) == 5) && !user_mode(regs))
+		goto bad_area_no_up;
+#endif
+
 	down_read(&mm->mmap_sem);
 
 	vma = find_vma_prev(mm, address, &prev_vma);
@@ -138,10 +148,16 @@
 
   bad_area:
 	up_read(&mm->mmap_sem);
-	if (isr & IA64_ISR_SP) {
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+  bad_area_no_up:
+#endif
+	if ((isr & IA64_ISR_SP)
+	    || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
+	{
 		/*
-		 * This fault was due to a speculative load set the "ed" bit in the psr to
-		 * ensure forward progress (target register will get a NaT).
+		 * This fault was due to a speculative load or lfetch.fault, set the "ed"
+		 * bit in the psr to ensure forward progress.  (Target register will get a
+		 * NaT for ld.s, lfetch will be canceled.)
 		 */
 		ia64_psr(regs)->ed = 1;
 		return;
@@ -167,15 +183,8 @@
 		return;
 	}
 
-#ifdef GAS_HAS_LOCAL_TAGS
-	fix = search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
-#else
-	fix = search_exception_table(regs->cr_iip);
-#endif
-	if (fix.cont) {
-		handle_exception(regs, fix);
+	if (done_with_exception(regs))
 		return;
-	}
 
 	/*
 	 * Oops. The kernel tried to access some bad page. We'll have to terminate things
diff -urN linux-2.4.20-pre6/arch/ia64/mm/init.c linux-2.4.20-pre7/arch/ia64/mm/init.c
--- linux-2.4.20-pre6/arch/ia64/mm/init.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/mm/init.c	Thu Sep 12 20:01:39 2002
@@ -1,8 +1,8 @@
 /*
  * Initialize MMU support.
  *
- * 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/config.h>
 #include <linux/kernel.h>
@@ -10,13 +10,14 @@
 
 #include <linux/bootmem.h>
 #include <linux/mm.h>
+#include <linux/personality.h>
 #include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
+#include <linux/efi.h>
 
 #include <asm/bitops.h>
 #include <asm/dma.h>
-#include <asm/efi.h>
 #include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
@@ -37,6 +38,13 @@
 
 static unsigned long totalram_pages;
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+unsigned long vmalloc_end = VMALLOC_END_INIT;
+
+static struct page *vmem_map;
+static unsigned long num_dma_physpages;
+#endif
+
 int
 do_check_pgt_cache (int low, int high)
 {
@@ -67,10 +75,9 @@
 	struct vm_area_struct *vma;
 
 	/*
-	 * If we're out of memory and kmem_cache_alloc() returns NULL,
-	 * we simply ignore the problem.  When the process attempts to
-	 * write to the register backing store for the first time, it
-	 * will get a SEGFAULT in this case.
+	 * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore
+	 * the problem.  When the process attempts to write to the register backing store
+	 * for the first time, it will get a SEGFAULT in this case.
 	 */
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (vma) {
@@ -85,6 +92,19 @@
 		vma->vm_private_data = NULL;
 		insert_vm_struct(current->mm, vma);
 	}
+
+	/* map NaT-page at address zero to speed up speculative dereferencing of NULL: */
+	if (!(current->personality & MMAP_PAGE_ZERO)) {
+		vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+		if (vma) {
+			memset(vma, 0, sizeof(*vma));
+			vma->vm_mm = current->mm;
+			vma->vm_end = PAGE_SIZE;
+			vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
+			vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED;
+			insert_vm_struct(current->mm, vma);
+		}
+	}
 }
 
 void
@@ -99,7 +119,7 @@
 		free_page(addr);
 		++totalram_pages;
 	}
-	printk (KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
+	printk(KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -141,7 +161,7 @@
 	end = end & PAGE_MASK;
 
 	if (start < end)
-		printk (KERN_INFO "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)))
@@ -204,6 +224,8 @@
 	printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	i = max_mapnr;
 	while (i-- > 0) {
+		if (!VALID_PAGE(mem_map + i))
+			continue;
 		total++;
 		if (PageReserved(mem_map+i))
 			reserved++;
@@ -261,7 +283,7 @@
 void __init
 ia64_mmu_init (void *my_cpu_data)
 {
-	unsigned long flags, rid, pta, impl_va_bits;
+	unsigned long psr, rid, pta, impl_va_bits;
 	extern void __init tlb_init (void);
 #ifdef CONFIG_DISABLE_VHPT
 #	define VHPT_ENABLE_BIT	0
@@ -273,7 +295,7 @@
 	 * Set up the kernel identity mapping for regions 6 and 5.  The mapping for region
 	 * 7 is setup up in _start().
 	 */
-	ia64_clear_ic(flags);
+	psr = ia64_clear_ic();
 
 	rid = ia64_rid(IA64_REGION_ID_KERNEL, __IA64_UNCACHED_OFFSET);
 	ia64_set_rr(__IA64_UNCACHED_OFFSET, (rid << 8) | (IA64_GRANULE_SHIFT << 2));
@@ -287,7 +309,7 @@
 	ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR,
 		 pte_val(mk_pte_phys(__pa(my_cpu_data), PAGE_KERNEL)), PAGE_SHIFT);
 
-	__restore_flags(flags);
+	ia64_set_psr(psr);
 	ia64_srlz_i();
 
 	/*
@@ -335,6 +357,135 @@
 	ia64_tlb_init();
 }
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+
+#include <asm/pgtable.h>
+
+static int
+create_mem_map_page_table (u64 start, u64 end, void *arg)
+{
+	unsigned long address, start_page, end_page;
+	struct page *map_start, *map_end;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	/* should we use platform_map_nr here? */
+
+	map_start = vmem_map + MAP_NR_DENSE(start);
+	map_end   = vmem_map + MAP_NR_DENSE(end);
+
+	start_page = (unsigned long) map_start & PAGE_MASK;
+	end_page = PAGE_ALIGN((unsigned long) map_end);
+
+	for (address = start_page; address < end_page; address += PAGE_SIZE) {
+		pgd = pgd_offset_k(address);
+		if (pgd_none(*pgd))
+			pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE));
+		pmd = pmd_offset(pgd, address);
+
+		if (pmd_none(*pmd))
+			pmd_populate(&init_mm, pmd, alloc_bootmem_pages(PAGE_SIZE));
+		pte = pte_offset(pmd, address);
+
+		if (pte_none(*pte))
+			set_pte(pte, mk_pte_phys(__pa(alloc_bootmem_pages(PAGE_SIZE)),
+						 PAGE_KERNEL));
+ 	}
+ 	return 0;
+}
+
+struct memmap_init_callback_data {
+	memmap_init_callback_t *memmap_init;
+	struct page *start;
+	struct page *end;
+	int zone;
+	int highmem;
+};
+
+static int
+virtual_memmap_init (u64 start, u64 end, void *arg)
+{
+	struct memmap_init_callback_data *args;
+	struct page *map_start, *map_end;
+
+	args = (struct memmap_init_callback_data *) arg;
+
+	/* Should we use platform_map_nr here? */
+
+	map_start = vmem_map + MAP_NR_DENSE(start);
+	map_end   = vmem_map + MAP_NR_DENSE(end);
+
+	if (map_start < args->start)
+		map_start = args->start;
+	if (map_end > args->end)
+		map_end = args->end;
+
+	/*
+	 * We have to initialize "out of bounds" struct page elements
+	 * that fit completely on the same pages that were allocated
+	 * for the "in bounds" elements because they may be referenced
+	 * later (and found to be "reserved").
+	 */
+	map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1))
+			/ sizeof(struct page);
+	map_end += ((PAGE_ALIGN((unsigned long) map_end) -
+				(unsigned long) map_end)
+			/ sizeof(struct page));
+
+	if (map_start < map_end)
+		(*args->memmap_init)(map_start, map_end, args->zone,
+				     page_to_phys(map_start), args->highmem);
+
+	return 0;
+}
+
+unsigned long
+arch_memmap_init (memmap_init_callback_t *memmap_init, struct page *start,
+	struct page *end, int zone, unsigned long start_paddr, int highmem)
+{
+	struct memmap_init_callback_data args;
+
+	args.memmap_init = memmap_init;
+	args.start = start;
+	args.end = end;
+	args.zone = zone;
+	args.highmem = highmem;
+
+	efi_memmap_walk(virtual_memmap_init, &args);
+
+	return page_to_phys(end);
+}
+
+static int
+count_dma_pages (u64 start, u64 end, void *arg)
+{
+	unsigned long *count = arg;
+
+	if (end <= MAX_DMA_ADDRESS)
+		*count += (end - start) >> PAGE_SHIFT;
+	return 0;
+}
+
+int
+ia64_page_valid (struct page *page)
+{
+	char byte;
+
+	return __get_user(byte, (char *) page) == 0;
+}
+
+#endif /* CONFIG_VIRTUAL_MEM_MAP */
+
+static int
+count_pages (u64 start, u64 end, void *arg)
+{
+	unsigned long *count = arg;
+
+	*count += (end - start) >> PAGE_SHIFT;
+	return 0;
+}
+
 /*
  * Set up the page tables.
  */
@@ -343,13 +494,49 @@
 {
 	unsigned long max_dma, zones_size[MAX_NR_ZONES];
 
-	clear_page((void *) ZERO_PAGE_ADDR);
-
 	/* initialize mem_map[] */
 
 	memset(zones_size, 0, sizeof(zones_size));
 
+	num_physpages = 0;
+	efi_memmap_walk(count_pages, &num_physpages);
+
 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+	{
+		unsigned long zholes_size[MAX_NR_ZONES];
+		unsigned long map_size;
+
+		memset(zholes_size, 0, sizeof(zholes_size));
+
+		num_dma_physpages = 0;
+		efi_memmap_walk(count_dma_pages, &num_dma_physpages);
+
+		if (max_low_pfn < max_dma) {
+			zones_size[ZONE_DMA] = max_low_pfn;
+			zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages;
+		} else {
+			zones_size[ZONE_DMA] = max_dma;
+			zholes_size[ZONE_DMA] = max_dma - num_dma_physpages;
+			if (num_physpages > num_dma_physpages) {
+				zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
+				zholes_size[ZONE_NORMAL] = ((max_low_pfn - max_dma)
+							    - (num_physpages - num_dma_physpages));
+			}
+		}
+
+		/* allocate virtual mem_map: */
+
+		map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page));
+		vmalloc_end -= map_size;
+		vmem_map = (struct page *) vmalloc_end;
+		efi_memmap_walk(create_mem_map_page_table, 0);
+
+		free_area_init_node(0, NULL, vmem_map, zones_size, 0, zholes_size);
+		printk("Virtual mem_map starts at 0x%p\n", mem_map);
+	}
+#else /* !CONFIG_VIRTUAL_MEM_MAP */
 	if (max_low_pfn < max_dma)
 		zones_size[ZONE_DMA] = max_low_pfn;
 	else {
@@ -357,15 +544,7 @@
 		zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
 	}
 	free_area_init(zones_size);
-}
-
-static int
-count_pages (u64 start, u64 end, void *arg)
-{
-	unsigned long *count = arg;
-
-	*count += (end - start) >> PAGE_SHIFT;
-	return 0;
+#endif /* !CONFIG_VIRTUAL_MEM_MAP */
 }
 
 static int
@@ -401,9 +580,6 @@
 	if (!mem_map)
 		BUG();
 
-	num_physpages = 0;
-	efi_memmap_walk(count_pages, &num_physpages);
-
 	max_mapnr = max_low_pfn;
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
@@ -416,10 +592,10 @@
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%luk code, %luk reserved, %luk data, %luk init)\n",
+	printk(KERN_INFO "Memory: %luk/%luk available (%luk code, %luk reserved, %luk data, %luk init)\n",
 	       (unsigned long) nr_free_pages() << (PAGE_SHIFT - 10),
-	       max_mapnr << (PAGE_SHIFT - 10), codesize >> 10, reserved_pages << (PAGE_SHIFT - 10),
-	       datasize >> 10, initsize >> 10);
+	       num_physpages << (PAGE_SHIFT - 10), codesize >> 10,
+	       reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10);
 
 	/*
 	 * Allow for enough (cached) page table pages so that we can map the entire memory
diff -urN linux-2.4.20-pre6/arch/ia64/mm/tlb.c linux-2.4.20-pre7/arch/ia64/mm/tlb.c
--- linux-2.4.20-pre6/arch/ia64/mm/tlb.c	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/arch/ia64/mm/tlb.c	Thu Sep 12 20:01:39 2002
@@ -79,7 +79,7 @@
 	flush_tlb_all();
 }
 
-static inline void
+void
 ia64_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
 {
 	static spinlock_t ptcg_lock = SPIN_LOCK_UNLOCKED;
diff -urN linux-2.4.20-pre6/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.20-pre7/arch/ia64/sn/fakeprom/fpmem.c
--- linux-2.4.20-pre6/arch/ia64/sn/fakeprom/fpmem.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/fakeprom/fpmem.c	Thu Sep 12 20:01:39 2002
@@ -18,7 +18,7 @@
  */
 
 #include <linux/config.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include "fpmem.h"
 
 /*
diff -urN linux-2.4.20-pre6/arch/ia64/sn/fakeprom/fw-emu.c linux-2.4.20-pre7/arch/ia64/sn/fakeprom/fw-emu.c
--- linux-2.4.20-pre6/arch/ia64/sn/fakeprom/fw-emu.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/fakeprom/fw-emu.c	Thu Sep 12 20:01:39 2002
@@ -36,7 +36,7 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 #include <linux/config.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
diff -urN linux-2.4.20-pre6/arch/ia64/sn/io/Makefile linux-2.4.20-pre7/arch/ia64/sn/io/Makefile
--- linux-2.4.20-pre6/arch/ia64/sn/io/Makefile	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/io/Makefile	Thu Sep 12 20:01:39 2002
@@ -18,7 +18,7 @@
 O_TARGET := sgiio.o
 
 ifeq ($(CONFIG_MODULES),y)
-export-objs = pciio.o hcl.o
+export-objs = pciio.o hcl.o pci_dma.o
 endif
 
 obj-y  := stubs.o sgi_if.o pciio.o xtalk.o xbow.o xswitch.o klgraph_hack.o \
diff -urN linux-2.4.20-pre6/arch/ia64/sn/io/efi-rtc.c linux-2.4.20-pre7/arch/ia64/sn/io/efi-rtc.c
--- linux-2.4.20-pre6/arch/ia64/sn/io/efi-rtc.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/io/efi-rtc.c	Thu Sep 12 20:01:39 2002
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/errno.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/sn/klclock.h>
 
 /*
diff -urN linux-2.4.20-pre6/arch/ia64/sn/io/pci_dma.c linux-2.4.20-pre7/arch/ia64/sn/io/pci_dma.c
--- linux-2.4.20-pre6/arch/ia64/sn/io/pci_dma.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/io/pci_dma.c	Thu Sep 12 20:01:39 2002
@@ -4,6 +4,9 @@
  * for more details.
  *
  * Copyright (C) 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ *
+ * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
+ * a description of how these routines should be used.
  */
 
 #include <linux/types.h>
@@ -12,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/module.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
@@ -27,15 +31,38 @@
 #include <asm/sn/pci/pci_bus_cvlink.h>
 #include <asm/sn/nag.h>
 
+/* DMA, PIO, and memory allocation flags */
+#ifdef CONFIG_IA64_SGI_SN1
+#define DMA_DATA_FLAGS		( PCIIO_BYTE_STREAM | PCIIO_DMA_DATA )
+#define DMA_CONTROL_FLAGS	( PCIIO_BYTE_STREAM | PCIBR_BARRIER | \
+				  PCIIO_DMA_CMD )
+#elif defined(CONFIG_IA64_SGI_SN2)
+#define DMA_DATA_FLAGS		( PCIIO_DMA_DATA )
+#define DMA_CONTROL_FLAGS	( PCIBR_BARRIER | PCIIO_DMA_CMD )
+#else
+#error need to define DMA mapping flags for this platform
+#endif
+
+/*
+ * For ATE allocations
+ */
 pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
 void free_pciio_dmamap(pcibr_dmamap_t);
-struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+
+/*
+ * Toplogy stuff
+ */
 extern devfs_handle_t busnum_to_pcibr_vhdl[];
 extern nasid_t busnum_to_nid[];
 extern void * busnum_to_atedmamaps[];
 
-/*
- * Get a free pciio_dmamap_t entry.
+/**
+ * get_free_pciio_dmamap - find and allocate an ATE
+ * @pci_bus: PCI bus to get an entry for
+ *
+ * Finds and allocates an ATE on the PCI bus specified
+ * by @pci_bus.
  */
 pciio_dmamap_t
 get_free_pciio_dmamap(devfs_handle_t pci_bus)
@@ -46,7 +73,7 @@
 	/*
 	 * Darn, we need to get the maps allocated for this bus.
 	 */
-	for (i=0; i<MAX_PCI_XWIDGET; i++) {
+	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
 		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
 			sn_dma_map = busnum_to_atedmamaps[i];
 		}
@@ -55,19 +82,21 @@
 	/*
 	 * Now get a free dmamap entry from this list.
 	 */
-	for (i=0; i<MAX_ATE_MAPS; i++, sn_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 );
 		}
 	}
 
-	return(NULL);
-
+	return NULL;
 }
 
-/*
- * Free pciio_dmamap_t entry.
+/**
+ * free_pciio_dmamap - free an ATE
+ * @dma_map: ATE to free
+ *
+ * Frees the ATE specified by @dma_map.
  */
 void
 free_pciio_dmamap(pcibr_dmamap_t dma_map)
@@ -76,177 +105,229 @@
 
 	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
 	sn_dma_map->dma_addr = 0;
+}
+
+/**
+ * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum
+ * @dma_addr: DMA address to look for
+ * @busnum: PCI bus to look on
+ *
+ * Finds the ATE associated with @dma_addr and @busnum.
+ */
+static struct sn_dma_maps_s *
+find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
+{
+
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+	int i;
+
+	sn_dma_map = busnum_to_atedmamaps[busnum];
+
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (sn_dma_map->dma_addr == dma_addr) {
+			return sn_dma_map;
+		}
+	}
 
+	printk(KERN_WARNING "find_sn_dma_map: Unable find the corresponding "
+	       "dma map\n");
+
+	return NULL;
 }
 
-/*
- * 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.
+/**
+ * sn_dma_sync - try to flush DMA buffers into the coherence domain
+ * @hwdev: device to flush
+ *
+ * This routine flushes all DMA buffers for the device into the II of
+ * the destination hub.
+ *
+ * NOTE!: this does not mean that the data is in the "coherence domain",
+ * but it is very close.  In other words, this routine *does not work*
+ * as advertised due to hardware bugs.  That said, it should be good enough for
+ * most situations.
  */
 void
-sn_dma_sync( struct pci_dev *hwdev )
+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.
+	 * It is expected that on an IA64 platform, a DMA sync ensures that 
+	 * all the DMA from a particular device is complete and coherent.  We
+	 * try to do this by
+	 *	1. flushing the write wuffers from Bridge
+	 *	2. flushing the Xbow port.
+	 * Unfortunately, this only gets the DMA transactions 'very close' to
+	 * the coherence domain, but not quite in it.
 	 */
 	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.
+	 * 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 sn_dma_maps_s *sn_dma_map = NULL;
-	int i;
-
-	sn_dma_map = busnum_to_atedmamaps[busnum];
-
-	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);
-
-}
-
-/*
- * sn1 platform specific pci_alloc_consistent()
+/**
+ * sn_pci_alloc_consistent - allocate memory for coherent DMA
+ * @hwdev: device to allocate for
+ * @size: size of the region
+ * @dma_handle: DMA (bus) address
+ *
+ * pci_alloc_consistent() returns a pointer to a memory region suitable for
+ * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
+ * that @dma_handle will have the PCIBR_BARRIER and PCIIO_DMA_CMD flags
+ * set.
  *
- * this interface is meant for "command" streams, i.e. called only
- * once for initializing a device, so we don't want prefetching or
- * write gathering turned on, hence the PCIIO_DMA_CMD flag
+ * This interface is usually used for "command" streams (e.g. the command
+ * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
+ * more information.  Note that this routine should always put a 32 bit
+ * DMA address into @dma_handle.  This is because most other platforms
+ * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_
+ * DMAs, and unfortunately this interface has to cater to the LCD.  Oh well.
+ *
+ * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
  */
 void *
-sn_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;
+        void *cpuaddr;
+	devfs_handle_t vhdl;
 	struct sn_device_sysdata *device_sysdata;
-	paddr_t temp_ptr;
+	unsigned long phys_addr;
+	pciio_dmamap_t dma_map = 0;
+	struct sn_dma_maps_s *sn_dma_map;
 
-	*dma_handle = (dma_addr_t) NULL;
+	*dma_handle = 0;
+
+	/* We can't easily support < 32 bit devices */
+	if (IS_PCI32L(hwdev))
+		return NULL;
 
 	/*
-	 * get vertex for the device
+	 * Get hwgraph vertex for the device
 	 */
 	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 
-        if ( (ret = (void *)__get_free_pages(gfp, get_order(size))) ) {
-		memset(ret, 0, size);
-	} else {
-		return(NULL);
-	}
-
-	temp_ptr = (paddr_t) __pa(ret);
-	if (IS_PCIA64(hwdev)) {
+	/*
+	 * Allocate the memory.  FIXME: if we're allocating for
+	 * two devices on the same bus, we should at least try to
+	 * allocate memory in the same 2 GB window to avoid using
+	 * ATEs for the translation.  See the comment above about the
+	 * 32 bit requirement for this function.
+	 */
+	if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+		return NULL;
 
-		/*
-		 * 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
+	memset(cpuaddr, 0, size); /* have to zero it out */
 
-		return (ret);
-	}
+	/* physical addr. of the memory we just got */
+	phys_addr = __pa(cpuaddr);
 
+	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+					  DMA_CONTROL_FLAGS);
 	/*
-	 * Devices that supports 32 Bits upto 63 Bits DMA Address gets
-	 * 32 Bits DMA addresses.
-	 *
-	 * First try to get 32 Bit Direct Map Support.
+	 * It is a 32 bit card and we cannot do direct mapping,
+	 * so we use an ATE.
 	 */
-	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("sn_pci_alloc_consistent: 32Bits DMA Page Map support not available yet!");
+	if (!(*dma_handle)) {
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
+					     DMA_CONTROL_FLAGS | PCIIO_FIXED);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
+			       "allocate anymore 32 bit page map entries.\n");
 			BUG();
 		}
-	}
-
-	if (IS_PCI32L(hwdev)) {
-		/*
-		 * SNIA64 cannot support DMA Addresses smaller than 32 bits.
-		 */
-		return (NULL);
-	}
+		*dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr,
+							     size);
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = *dma_handle;
+		printk(KERN_INFO "%s: PMU mapping: %p\n", __FUNCTION__,
+		       (void *)*dma_handle);
+	}
+	else
+		printk(KERN_INFO "%s: direct mapping: %p\n", __FUNCTION__,
+		       (void *)*dma_handle);
+	
 
-        return NULL;
+        return cpuaddr;
 }
 
+/**
+ * sn_pci_free_consistent - free memory associated with coherent DMAable region
+ * @hwdev: device to free for
+ * @size: size to free
+ * @vaddr: kernel virtual address to free
+ * @dma_handle: DMA address associated with this region
+ *
+ * Frees the memory allocated by pci_alloc_consistent().  Also known
+ * as platform_pci_free_consistent() by the IA64 machvec code.
+ */
 void
 sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_handle))
+		sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number);
+
+	/*
+	 * and free it if necessary...
+	 */
+	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;
+	}
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
-/*
- * On sn1 we use the page entry of the scatterlist to store
- * the physical address corresponding to the given virtual address
+/**
+ * sn_pci_map_sg - map a scatter-gather list for DMA
+ * @hwdev: device to map for
+ * @sg: scatterlist to map
+ * @nents: number of entries
+ * @direction: direction of the DMA transaction
+ *
+ * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
+ * IA64 machvec code.
  */
 int
-sn_pci_map_sg (struct pci_dev *hwdev,
-                        struct scatterlist *sg, int nents, int direction)
+sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
 {
 
 	int i;
-	devfs_handle_t	vhdl;
+	devfs_handle_t vhdl;
 	dma_addr_t dma_addr;
-	paddr_t temp_ptr;
+	unsigned long phys_addr;
 	struct sn_device_sysdata *device_sysdata;
 	pciio_dmamap_t dma_map;
 
-
-
+	/* can't go anywhere w/o a direction in life */
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
 	/*
-	 * Handle 64 bit cards.
+	 * Get the hwgraph vertex for the device
 	 */
 	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Setup a DMA address for each entry in the
+	 * scatterlist.
+	 */
 	for (i = 0; i < nents; i++, sg++) {
 		/* this catches incorrectly written drivers that
                    attempt to map scatterlists that they have
@@ -262,50 +343,37 @@
 			    "%p - this is currently being worked around.\n",
 			    hwdev->slot_name, (void *)sg->address);
 #endif
-			temp_ptr = (u64)sg->address & TO_PHYS_MASK;
+			phys_addr = (u64)sg->address & TO_PHYS_MASK;
 			break;
-		case 0xe: /* a good address, we now map it. */
-			temp_ptr = (paddr_t) __pa(sg->address);
+		default: /* not previously mapped, get the phys. addr */
+			phys_addr = __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;
+		sg->page = NULL;
 		dma_addr = 0;
 
 		/*
-		 * Handle the most common case 64Bit cards.
+		 * Handle the most common case: 64 bit cards.  This
+		 * call should always succeed.
 		 */
 		if (IS_PCIA64(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-				temp_ptr, sg->length,
-				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
+			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+						       DMA_DATA_FLAGS | PCIIO_DMA_A64 );
 			sg->address = (char *)dma_addr;
 			continue;
 		}
 
 		/*
-		 * Handle 32Bits and greater cards.
+		 * Handle 32-63 bit cards via direct mapping
 		 */
 		if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-				temp_ptr, sg->length,
-				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
+			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+						       DMA_DATA_FLAGS);
+			/*
+			 * See if we got a direct map entry
+			 */
 			if (dma_addr) {
 				sg->address = (char *)dma_addr;
 				continue;
@@ -314,22 +382,18 @@
 		}
 
 		/*
-		 * It is a 32bit card and we cannot do Direct mapping.
-		 * Let's 32Bit Page map the request.
+		 * It is a 32 bit card and we cannot do direct mapping,
+		 * so we use an ATE.
 		 */
-		dma_map = NULL;
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, 
-				PCIIO_BYTE_STREAM | PCIIO_DMA_DATA);
-#else
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, PCIIO_DMA_DATA);
-#endif
+		dma_map = 0;
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
+					     DMA_DATA_FLAGS);
 		if (!dma_map) {
-			printk("pci_map_sg: Unable to allocate anymore 32Bits Page Map entries.\n");
+			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
+			       "anymore 32 bit page map entries.\n");
 			BUG();
 		}
-		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); */
+		dma_addr = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
 		sg->address = (char *)dma_addr;
 		sg->page = (char *)dma_map;
 		
@@ -339,30 +403,34 @@
 
 }
 
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
+/**
+ * sn_pci_unmap_sg - unmap a scatter-gather list
+ * @hwdev: device to unmap
+ * @sg: scatterlist to unmap
+ * @nents: number of scatterlist entries
+ * @direction: DMA direction
+ *
+ * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
+ * concerning calls here are the same as for pci_unmap_single() below.  Also
+ * known as sn_pci_unmap_sg() by the IA64 machvec code.
  */
 void
-sn_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 nents, int direction)
 {
 	int i;
 	struct sn_dma_maps_s *sn_dma_map;
 
-
+	/* can't go anywhere w/o a direction in life */
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
-	for (i = 0; i < nelems; i++, sg++)
+	for (i = 0; i < nents; i++, sg++)
 		if (sg->page) {
 			/*
 			 * 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->page; */
-			sg->address = (char *)-1;
+			sg->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);
@@ -372,7 +440,17 @@
 
 }
 
-/*
+/**
+ * sn_pci_map_single - map a single region for DMA
+ * @hwdev: device to map for
+ * @ptr: kernel virtual address of the region to map
+ * @size: size of the region
+ * @direction: DMA direction
+ *
+ * Map the region pointed to by @ptr for DMA and return the
+ * DMA address.   Also known as platform_pci_map_single() by
+ * the IA64 machvec code.
+ *
  * We map this to the one step pciio_dmamap_trans interface rather than
  * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have
  * no way of saving the dmamap handle from the alloc to later free
@@ -382,20 +460,21 @@
  *       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 sn_pci_map_single (struct pci_dev *hwdev,
-				void *ptr, size_t size, int direction)
+dma_addr_t
+sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
-	devfs_handle_t	vhdl;
+	devfs_handle_t vhdl;
 	dma_addr_t dma_addr;
-	paddr_t temp_ptr;
+	unsigned long phys_addr;
 	struct sn_device_sysdata *device_sysdata;
 	pciio_dmamap_t dma_map = NULL;
 	struct sn_dma_maps_s *sn_dma_map;
 
-
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
+	/* SN cannot support DMA addresses smaller than 32 bits. */
+	if (IS_PCI32L(hwdev)) return 0;
 
 	/*
 	 * find vertex for the device
@@ -407,79 +486,63 @@
 	 * Call our dmamap interface
 	 */
 	dma_addr = 0;
-	temp_ptr = (paddr_t) __pa(ptr);
+	phys_addr = __pa(ptr);
 
 	if (IS_PCIA64(hwdev)) {
 		/*
-		 * This device supports 64bits DMA addresses.
+		 * This device supports 64 bit DMA addresses.
 		 */
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-			temp_ptr, size,
-			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);
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+					       DMA_DATA_FLAGS | PCIIO_DMA_A64);
+		return dma_addr;
 	}
 
 	/*
-	 * Devices that supports 32 Bits upto 63 Bits DMA Address gets
-	 * 32 Bits DMA addresses.
+	 * Devices that supports 32 bit to 63 bit DMA addresses get
+	 * 32 bit DMA addresses.
 	 *
-	 * First try to get 32 Bit Direct Map Support.
+	 * First try to get a 32 bit direct map register.
 	 */
 	if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL,
-			temp_ptr, size,
-			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);
-		}
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+					       DMA_DATA_FLAGS);
+		if (dma_addr)
+			return dma_addr;
 	}
 
-	if (IS_PCI32L(hwdev)) {
-		/*
-		 * SNIA64 cannot support DMA Addresses smaller than 32 bits.
-		 */
-		return ((dma_addr_t) NULL);
-        }
-
 	/*
-	 * It is a 32bit card and we cannot do Direct mapping.
-	 * Let's 32Bit Page map the request.
+	 * It's a 32 bit card and we cannot do direct mapping so
+	 * let's use the PMU instead.
 	 */
 	dma_map = NULL;
-#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
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, DMA_DATA_FLAGS);
+
 	if (!dma_map) {
-		printk("pci_map_single: Unable to allocate anymore 32Bits Page Map entries.\n");
+		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
+		       "32 bits 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,
-		temp_ptr, dma_addr); */
+	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size);
 	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
 	sn_dma_map->dma_addr = dma_addr;
 
 	return ((dma_addr_t)dma_addr);
 }
 
+/**
+ * sn_pci_unmap_single - unmap a region used for DMA
+ * @hwdev: device to unmap
+ * @dma_addr: DMA address to unmap
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * Unmaps the region pointed to by @dma_addr.  Also known as
+ * platform_pci_unmap_single() by the IA64 machvec code.
+ */
 void
-sn_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 sn_dma_maps_s *sn_dma_map = NULL;
 
         if (direction == PCI_DMA_NONE)
@@ -491,37 +554,97 @@
 	if (IS_PCI32_MAPPED(dma_addr))
 		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
 
+	/*
+	 * and free it if necessary...
+	 */
 	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;
 	}
-
 }
 
+/**
+ * sn_pci_dma_sync_single - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @dma_handle: DMA address to sync
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA region specified
+ * by @dma_handle into the 'coherence domain'.  See sn_dma_sync()
+ * above for more information.   Also known as
+ * platform_pci_dma_sync_single() by the IA64 machvec code.
+ */
 void
-sn_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)
+	if (direction == PCI_DMA_NONE)
                 BUG();
 
 	sn_dma_sync(hwdev);
-
 }
 
+/**
+ * sn_pci_dma_sync_sg - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @sg: scatterlist to sync
+ * @nents: number of entries in the scatterlist
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA regions specified
+ * by @sg into the 'coherence domain'.  See sn_dma_sync()
+ * above for more information.   Also known as
+ * platform_pci_dma_sync_sg() by the IA64 machvec code.
+ */
 void
-sn_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 nents, int direction)
 {
         if (direction == PCI_DMA_NONE)
                 BUG();
 
 	sn_dma_sync(hwdev);
-
 }
 
+/**
+ * sn_dma_address - get the DMA address for the first entry of a scatterlist
+ * @sg: sg to look at
+ *
+ * Gets the DMA address for the scatterlist @sg.  Also known as
+ * platform_dma_address() by the IA64 machvec code.
+ */
 unsigned long
-sn_dma_address (struct scatterlist *sg)
+sn_dma_address(struct scatterlist *sg)
 {
 	return ((unsigned long)sg->address);
 }
+
+/**
+ * sn_dma_supported - test a DMA mask
+ * @hwdev: device to test
+ * @mask: DMA mask to test
+ *
+ * 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.  Of course, SN only supports devices that have 32 or more
+ * address bits.
+ */
+int
+sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+	if (mask < 0xffffffff)
+		return 0;
+	return 1;
+}
+
+EXPORT_SYMBOL(sn_pci_unmap_single);
+EXPORT_SYMBOL(sn_pci_map_single);
+EXPORT_SYMBOL(sn_pci_dma_sync_single);
+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);
+EXPORT_SYMBOL(sn_pci_dma_supported);
+
diff -urN linux-2.4.20-pre6/arch/ia64/sn/kernel/llsc4.c linux-2.4.20-pre7/arch/ia64/sn/kernel/llsc4.c
--- linux-2.4.20-pre6/arch/ia64/sn/kernel/llsc4.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/kernel/llsc4.c	Thu Sep 12 20:01:39 2002
@@ -17,7 +17,7 @@
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/string.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include <asm/page.h>
 #include <linux/threads.h>
 #include <asm/sn/simulator.h>
diff -urN linux-2.4.20-pre6/arch/ia64/sn/kernel/misctest.c linux-2.4.20-pre7/arch/ia64/sn/kernel/misctest.c
--- linux-2.4.20-pre6/arch/ia64/sn/kernel/misctest.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/kernel/misctest.c	Thu Sep 12 20:01:39 2002
@@ -75,7 +75,7 @@
 	if (mcatest == 5) {
 		int zzzspec(long);
 		int	i;
-		long	flags, dcr, res, val, addr=0xff00000000UL;
+		long	psr, dcr, res, val, addr=0xff00000000UL;
 
 		dcr = ia64_get_dcr();
 		for (i=0; i<5; i++) {
@@ -87,11 +87,11 @@
 			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);
+			psr = ia64_clear_ic();
 			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_set_psr(psr);
 			ia64_srlz_i ();
 		}
 
diff -urN linux-2.4.20-pre6/arch/ia64/sn/kernel/sn_ksyms.c linux-2.4.20-pre7/arch/ia64/sn/kernel/sn_ksyms.c
--- linux-2.4.20-pre6/arch/ia64/sn/kernel/sn_ksyms.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/ia64/sn/kernel/sn_ksyms.c	Thu Sep 12 20:01:39 2002
@@ -17,15 +17,6 @@
 #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[];
@@ -62,6 +53,4 @@
 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 -urN linux-2.4.20-pre6/arch/ia64/tools/Makefile linux-2.4.20-pre7/arch/ia64/tools/Makefile
--- linux-2.4.20-pre6/arch/ia64/tools/Makefile	Mon Feb 25 11:37:53 2002
+++ linux-2.4.20-pre7/arch/ia64/tools/Makefile	Thu Sep 12 20:01:39 2002
@@ -2,9 +2,9 @@
 
 TARGET	= $(TOPDIR)/include/asm-ia64/offsets.h
 
-all: 
+all:
 
-mrproper:
+mrproper: clean
 
 clean:
 	rm -f print_offsets.s print_offsets offsets.h
diff -urN linux-2.4.20-pre6/arch/ia64/tools/print_offsets.c linux-2.4.20-pre7/arch/ia64/tools/print_offsets.c
--- linux-2.4.20-pre6/arch/ia64/tools/print_offsets.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/ia64/tools/print_offsets.c	Thu Sep 12 20:01:39 2002
@@ -58,7 +58,8 @@
     { "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_OVFL_BLOCK_RESET_OFFSET",offsetof(struct task_struct, thread.pfm_ovfl_block_reset) },
+    { "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) },
@@ -152,6 +153,7 @@
     { "IA64_SWITCH_STACK_AR_RNAT_OFFSET",	offsetof (struct switch_stack, ar_rnat) },
     { "IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET",	offsetof (struct switch_stack, ar_bspstore) },
     { "IA64_SWITCH_STACK_PR_OFFSET",	offsetof (struct switch_stack, pr) },
+    { "IA64_SIGCONTEXT_IP_OFFSET",	offsetof (struct sigcontext, sc_ip) },
     { "IA64_SIGCONTEXT_AR_BSP_OFFSET",	offsetof (struct sigcontext, sc_ar_bsp) },
     { "IA64_SIGCONTEXT_AR_FPSR_OFFSET", offsetof (struct sigcontext, sc_ar_fpsr) },
     { "IA64_SIGCONTEXT_AR_RNAT_OFFSET",	offsetof (struct sigcontext, sc_ar_rnat) },
diff -urN linux-2.4.20-pre6/arch/ia64/vmlinux.lds.S linux-2.4.20-pre7/arch/ia64/vmlinux.lds.S
--- linux-2.4.20-pre6/arch/ia64/vmlinux.lds.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/ia64/vmlinux.lds.S	Thu Sep 12 20:01:39 2002
@@ -1,5 +1,6 @@
 #include <linux/config.h>
 
+#include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/system.h>
 
@@ -27,11 +28,6 @@
   .text : AT(ADDR(.text) - PAGE_OFFSET)
     {
 	*(.text.ivt)
-	/* these are not really text pages, but they need to be page aligned: */
-	*(__special_page_section)
-	__start_gate_section = .;
-	*(.text.gate)
-	__stop_gate_section = .;
 	*(.text)
     }
   .text2 : AT(ADDR(.text2) - PAGE_OFFSET)
@@ -44,8 +40,6 @@
 
   /* Read-only data */
 
-  __gp = ALIGN(16) + 0x200000;	/* gp must be 16-byte aligned for exc. table */
-
   /* Global data */
   _data = .;
 
@@ -117,9 +111,13 @@
 	{ *(init_task) }
 
   .data.page_aligned : AT(ADDR(.data.page_aligned) - PAGE_OFFSET)
-        { *(.data.idt) }
+        { *(__special_page_section)
+	  __start_gate_section = .;
+	  *(.text.gate)
+	  __stop_gate_section = .;
+	}
 
-  . = ALIGN(64);
+  . = ALIGN(SMP_CACHE_BYTES);
   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - PAGE_OFFSET)
         { *(.data.cacheline_aligned) }
 
@@ -130,6 +128,10 @@
   .data : AT(ADDR(.data) - PAGE_OFFSET)
 	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
 
+
+  . = ALIGN(16);
+  __gp = . + 0x200000;	/* gp must be 16-byte aligned for exc. table */
+
   .got : AT(ADDR(.got) - PAGE_OFFSET)
 	{ *(.got.plt) *(.got) }
   /* We want the small data sections together, so single-instruction offsets
diff -urN linux-2.4.20-pre6/arch/m68k/kernel/entry.S linux-2.4.20-pre7/arch/m68k/kernel/entry.S
--- linux-2.4.20-pre6/arch/m68k/kernel/entry.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/m68k/kernel/entry.S	Thu Sep 12 20:01:39 2002
@@ -645,6 +645,18 @@
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_gettid)
 	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)	/* 225 */
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
 
 	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -urN linux-2.4.20-pre6/arch/mips/Makefile linux-2.4.20-pre7/arch/mips/Makefile
--- linux-2.4.20-pre6/arch/mips/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/Makefile	Thu Sep 12 20:01:39 2002
@@ -27,7 +27,7 @@
 endif
 
 #
-# GCC uses -G0 -mabicalls -fpic as default.  We don't want PIC in the kernel
+# GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
 # code since it only slows down the whole thing.  At some point we might make
 # use of global pointer optimizations but their use of $28 conflicts with
 # the current pointer optimization.
@@ -141,7 +141,17 @@
 endif
 
 #
-# Au1000 (Alchemy Semi PB1500) eval board
+# Au1100 (Alchemy Semi PB1100) eval board
+#
+ifdef CONFIG_MIPS_PB1100
+LIBS          += arch/mips/au1000/pb1100/pb1100.o \
+                 arch/mips/au1000/common/au1000.o
+SUBDIRS       += arch/mips/au1000/pb1100 arch/mips/au1000/common
+LOADADDR      += 0x80100000
+endif
+
+#
+# Au1500 (Alchemy Semi PB1500) eval board
 #
 ifdef CONFIG_MIPS_PB1500
 LIBS		+= arch/mips/au1000/pb1500/pb1500.o \
@@ -257,6 +267,16 @@
 endif
 
 #
+# MIPS SEAD board
+#
+ifdef CONFIG_MIPS_SEAD
+LIBS		+= arch/mips/mips-boards/sead/sead.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/sead
+LOADADDR	:= 0x80100000
+endif
+
+#
 # Momentum Ocelot board
 #
 ifdef CONFIG_MOMENCO_OCELOT
@@ -269,11 +289,22 @@
 endif
 
 #
+# Momentum Ocelot-G board
+#
+ifdef CONFIG_MOMENCO_OCELOT_G
+# The Ocelot-G setup.o must be linked early - it does the ioremap() for the
+# mips_io_port_base.
+CORE_FILES	+= arch/mips/momentum/ocelot_g/ocelot_g.o
+SUBDIRS		+= arch/mips/momentum/ocelot_g
+LOADADDR	:= 0x80100000
+endif
+
+#
 # NEC DDB Vrc-5074
 #
 ifdef CONFIG_DDB5074
-SUBDIRS		+= arch/mips/ddb5074
-LIBS		+= arch/mips/ddb5074/ddb5074.a
+SUBDIRS		+= arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5074
+LIBS		+= arch/mips/ddb5xxx/common/ddb5xxx.o arch/mips/ddb5xxx/ddb5074/ddb5074.o
 LOADADDR	:= 0x80080000
 endif
 
@@ -294,7 +325,7 @@
 SUBDIRS		+= arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5477
 LIBS		+= arch/mips/ddb5xxx/common/ddb5xxx.o \
 		   arch/mips/ddb5xxx/ddb5477/ddb5477.o
-LOADADDR	:= 0x80080000
+LOADADDR	:= 0x80100000
 endif
 
 #
@@ -308,6 +339,28 @@
 endif
 
 #
+# NEC Eagle/Hawk (VR4122/VR4131) board
+#
+ifdef CONFIG_NEC_EAGLE
+SUBDIRS		+= arch/mips/vr41xx/common \
+		   arch/mips/vr41xx/nec-eagle
+LIBS		+= arch/mips/vr41xx/common/vr41xx.o \
+		   arch/mips/vr41xx/nec-eagle/eagle.o
+LOADADDR	:= 0x80000000
+endif
+
+#
+# ZAO Networks Capcella (VR4131)
+#
+ifdef CONFIG_ZAO_CAPCELLA
+SUBDIRS		+= arch/mips/vr41xx/common \
+		   arch/mips/vr41xx/zao-capcella
+LIBS		+= arch/mips/vr41xx/common/vr41xx.o \
+		   arch/mips/vr41xx/zao-capcella/capcella.o
+LOADADDR	:= 0x80000000
+endif
+
+#
 # Philips Nino
 #
 ifdef CONFIG_NINO
@@ -352,6 +405,14 @@
 endif
 
 #
+# Sibyte CFE firmware
+#
+ifdef CONFIG_SIBYTE_CFE
+LIBS		+= arch/mips/sibyte/cfe/cfe.a
+SUBDIRS		+= arch/mips/sibyte/cfe
+endif
+
+#
 # SB1 Cache Error handler
 #
 ifdef CONFIG_SB1_CACHE_ERROR
diff -urN linux-2.4.20-pre6/arch/mips/arc/Makefile linux-2.4.20-pre7/arch/mips/arc/Makefile
--- linux-2.4.20-pre6/arch/mips/arc/Makefile	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/arc/Makefile	Thu Sep 12 20:01:39 2002
@@ -1,18 +1,13 @@
 #
-# Makefile for the SGI arcs prom monitor library routines
-# under Linux.
+# Makefile for the ARC prom monitor library 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...
 
 L_TARGET = arclib.a
 
-obj-y		+= console.o init.o memory.o tree.o env.o cmdline.o misc.o \
-		   time.o file.o identify.o
+obj-y				+= cmdline.o console.o env.o file.o \
+				   identify.o init.o misc.o time.o tree.o
 
-obj-$(CONFIG_ARC_CONSOLE)   += arc_con.o
+obj-$(CONFIG_ARC_MEMORY)	+= memory.o
+obj-$(CONFIG_ARC_CONSOLE)	+= arc_con.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/arc/arc_con.c linux-2.4.20-pre7/arch/mips/arc/arc_con.c
--- linux-2.4.20-pre6/arch/mips/arc/arc_con.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/arc/arc_con.c	Thu Sep 12 20:01:39 2002
@@ -2,61 +2,49 @@
  * Wrap-around code for a console using the
  * ARC io-routines.
  *
- * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (c) 2001 Ralf Baechle
+ * Copyright (c) 2002 Thiemo Seufer
  */
-
 #include <linux/tty.h>
 #include <linux/major.h>
 #include <linux/ptrace.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/fs.h>
-
-extern char prom_getchar (void);
-extern void prom_printf (char *, ...);
+#include <asm/sgialib.h>
 
 static void prom_console_write(struct console *co, const char *s,
 			       unsigned count)
 {
-	unsigned i;
-
-	/*
-	 *    Now, do each character
-	 */
-	for (i = 0; i < count; i++) {
-		if (*s == 10)
-			prom_printf("%c", 13);
-		prom_printf("%c", *s++);
+	/* Do each character */
+	while (count--) {
+		if (*s == '\n')
+			prom_putchar('\r');
+		prom_putchar(*s++);
 	}
 }
 
-static int prom_console_wait_key(struct console *co)
+static kdev_t prom_console_device(struct console *co)
 {
-	return prom_getchar();
+	return MKDEV(TTY_MAJOR, 64 + co->index);
 }
 
 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);
+	if (prom_flags & PROM_FLAG_USE_AS_CONSOLE)
+		return 0;
+	else
+		return 1;
 }
 
 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,
+	setup:		prom_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
 };
 
 /*
diff -urN linux-2.4.20-pre6/arch/mips/arc/cmdline.c linux-2.4.20-pre7/arch/mips/arc/cmdline.c
--- linux-2.4.20-pre6/arch/mips/arc/cmdline.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/arc/cmdline.c	Thu Sep 12 20:01:39 2002
@@ -1,4 +1,8 @@
 /*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * cmdline.c: Kernel command line creation using ARCS argc/argv.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -46,13 +50,13 @@
 		for(i = 0; i < NENTS(used_arc); i++) {
 			int len = strlen(used_arc[i][0]);
 
-			if(!strncmp(prom_argv[actr], used_arc[i][0], len)) {
+			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
 			/* Ok, we want it. First append the replacement... */
 				strcat(cp, used_arc[i][1]);
 				cp += strlen(used_arc[i][1]);
 				/* ... and now the argument */
-				s = strstr(prom_argv[actr], "=");
-				if(s) {
+				s = strstr(prom_argv(actr), "=");
+				if (s) {
 					s++;
 					strcpy(cp, s);
 					cp += strlen(s);
@@ -76,7 +80,7 @@
 	actr = 1; /* Always ignore argv[0] */
 
 	cp = &(arcs_cmdline[0]);
-	/* 
+	/*
 	 * Move ARC variables to the beginning to make sure they can be
 	 * overridden by later arguments.
 	 */
@@ -86,12 +90,12 @@
 		for (i = 0; i < NENTS(ignored); i++) {
 			int len = strlen(ignored[i]);
 
-			if(!strncmp(prom_argv[actr], ignored[i], len))
+			if (!strncmp(prom_argv(actr), ignored[i], len))
 				goto pic_cont;
 		}
 		/* Ok, we want it. */
-		strcpy(cp, prom_argv[actr]);
-		cp += strlen(prom_argv[actr]);
+		strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
 		*cp++ = ' ';
 
 	pic_cont:
diff -urN linux-2.4.20-pre6/arch/mips/arc/console.c linux-2.4.20-pre7/arch/mips/arc/console.c
--- linux-2.4.20-pre6/arch/mips/arc/console.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/arc/console.c	Thu Sep 12 20:01:39 2002
@@ -6,13 +6,9 @@
  * Copyright (C) 1996 David S. Miller (dm@sgi.com)
  * Compability with board caches, Ulf Carlsson
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <asm/sgialib.h>
 #include <asm/bcache.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
 
 /*
  * IP22 boardcache is not compatible with board caches.  Thus we disable it
@@ -26,18 +22,18 @@
 
 void prom_putchar(char c)
 {
-	long cnt;
-	char it = c;
+	ULONG cnt;
+	CHAR it = c;
 
 	bc_disable();
 	ArcWrite(1, &it, 1, &cnt);
 	bc_enable();
 }
 
-char __init prom_getchar(void)
+char prom_getchar(void)
 {
-	long cnt;
-	char c;
+	ULONG cnt;
+	CHAR c;
 
 	bc_disable();
 	ArcRead(0, &c, 1, &cnt);
@@ -46,24 +42,22 @@
 	return c;
 }
 
-static char ppbuf[1024];
-
 void prom_printf(char *fmt, ...)
 {
 	va_list args;
-	char ch, *bptr;
-	int i;
+	char ppbuf[1024];
+	char *bptr;
 
 	va_start(args, fmt);
-	i = vsprintf(ppbuf, fmt, args);
+	vsprintf(ppbuf, fmt, args);
 
 	bptr = ppbuf;
 
-	while ((ch = *(bptr++)) != 0) {
-		if (ch == '\n')
+	while (*bptr != 0) {
+		if (*bptr == '\n')
 			prom_putchar('\r');
 
-		prom_putchar(ch);
+		prom_putchar(*bptr++);
 	}
 	va_end(args);
 }
diff -urN linux-2.4.20-pre6/arch/mips/arc/identify.c linux-2.4.20-pre7/arch/mips/arc/identify.c
--- linux-2.4.20-pre6/arch/mips/arc/identify.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/arc/identify.c	Thu Sep 12 20:01:39 2002
@@ -1,10 +1,14 @@
 /*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * identify.c: identify machine by looking up system identifier
  *
  * Copyright (C) 1998 Thomas Bogendoerfer
- * 
+ *
  * This code is based on arch/mips/sgi/kernel/system.c, which is
- * 
+ *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/config.h>
@@ -13,7 +17,6 @@
 #include <linux/types.h>
 #include <linux/string.h>
 
-#include <asm/sgi/sgi.h>
 #include <asm/sgialib.h>
 #include <asm/bootinfo.h>
 
@@ -31,6 +34,21 @@
 		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,
@@ -51,7 +69,7 @@
 
 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;
 
@@ -77,15 +95,16 @@
 	const char *iname;
 
 	/*
-	 * The root component tells us what machine architecture we
-	 * have here.
+	 * The root component tells us what machine architecture we have here.
 	 */
 	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.  */
+		/* IP27 PROM misbehaves, seems to not implement ARC
+		   GetChild().  So we just assume it's an IP27.  */
 		iname = "SGI-IP27";
+#else
+		iname = "Unknown";
 #endif
 	} else
 		iname = (char *) (long) p->iname;
diff -urN linux-2.4.20-pre6/arch/mips/arc/init.c linux-2.4.20-pre7/arch/mips/arc/init.c
--- linux-2.4.20-pre6/arch/mips/arc/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/arc/init.c	Thu Sep 12 20:01:39 2002
@@ -1,5 +1,5 @@
 /*
- * This file is subject to the terms and conditions of the GNU General Public+ 
+ * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
@@ -17,20 +17,15 @@
 /* Master romvec interface. */
 struct linux_romvec *romvec;
 int prom_argc;
-char **prom_argv, **prom_envp;
-
-extern void prom_testtree(void);
+LONG *_prom_argv, *_prom_envp;
 
 void __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
 {
-	PSYSTEM_PARAMETER_BLOCK pb;
-	unsigned short prom_vers, prom_rev;
-
+	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
 	romvec = ROMVECTOR;
-	pb = PROMBLOCK;
 	prom_argc = argc;
-	prom_argv = argv;
-	prom_envp = envp;
+	_prom_argv = (LONG *) argv;
+	_prom_envp = (LONG *) envp;
 
 	if (pb->magic != 0x53435241) {
 		prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
@@ -39,19 +34,14 @@
 	}
 
 	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();
-		romvec->imode();
-	}
+	prom_printf("Press a key to reboot\n");
+	prom_getchar();
+	ArcEnterInteractiveMode();
 #endif
 }
diff -urN linux-2.4.20-pre6/arch/mips/arc/memory.c linux-2.4.20-pre7/arch/mips/arc/memory.c
--- linux-2.4.20-pre6/arch/mips/arc/memory.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/arc/memory.c	Thu Sep 12 20:01:39 2002
@@ -2,7 +2,14 @@
  * memory.c: PROM library functions for acquiring/using memory descriptors
  *           given to us from the ARCS firmware.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 by David S. Miller
+ * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to us
+ * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
+ * because on some machines like SGI IP27 the ARC memory configuration data
+ * completly bogus and alternate easier to use mechanisms are available.
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -19,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);
 }
@@ -47,7 +53,8 @@
 	"FirmwarePermanent",
 	"FreeContiguous"
 };
-#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc]
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
+						: arc_mtypes[a.arc]
 #endif
 
 static inline int memtype_classify_arcs (union linux_memtypes type)
@@ -92,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);
@@ -128,8 +135,7 @@
 	}
 }
 
-void __init
-prom_free_prom_memory (void)
+void __init prom_free_prom_memory (void)
 {
 	unsigned long freed = 0;
 	unsigned long addr;
@@ -149,5 +155,5 @@
 			freed += PAGE_SIZE;
 		}
 	}
-	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+	printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
 }
diff -urN linux-2.4.20-pre6/arch/mips/arc/salone.c linux-2.4.20-pre7/arch/mips/arc/salone.c
--- linux-2.4.20-pre6/arch/mips/arc/salone.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/arc/salone.c	Thu Sep 12 20:01:39 2002
@@ -1,23 +1,24 @@
 /*
- * salone.c: Routines to load into memory and execute stand-along
- *           program images using ARCS PROM firmware.
+ * Routines to load into memory and execute stand-along program images using
+ * ARCS PROM firmware.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
 
-long __init prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr)
+LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
 {
-	return romvec->load(name, end, pc, eaddr);
+	return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
 }
 
-long __init prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp)
+LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
+	CHAR *Envp[])
 {
-	return romvec->invoke(pc, sp, argc, argv, envp);
+	return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
 }
 
-long __init prom_exec(char *name, long argc, char **argv, char **envp)
+LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
 {
-	return romvec->exec(name, argc, argv, envp);
+	return ARC_CALL4(exec, Path, Argc, Argv, Envp);
 }
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/Makefile linux-2.4.20-pre7/arch/mips/au1000/common/Makefile
--- linux-2.4.20-pre6/arch/mips/au1000/common/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/Makefile	Thu Sep 12 20:01:39 2002
@@ -10,22 +10,20 @@
 # 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
 
 all: au1000.o
 
 O_TARGET := au1000.o
 
-export-objs		= prom.o serial.o clocks.o
+export-objs		= prom.o serial.o clocks.o power.o usbdev.o
 
-obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o power.o clocks.o
+obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o \
+	clocks.o power.o usbdev.o
 
-obj-$(CONFIG_AU1000_UART) += serial.o             
+obj-$(CONFIG_AU1000_UART) += serial.o
 obj-$(CONFIG_AU1000_USB_DEVICE) += usbdev.o
-obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o             
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
 obj-$(CONFIG_RTC) += rtc.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/clocks.c linux-2.4.20-pre7/arch/mips/au1000/common/clocks.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/clocks.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/clocks.c	Thu Sep 12 20:01:39 2002
@@ -75,9 +75,9 @@
 	unsigned int static_cfg0;
 	unsigned int sys_busclk =
 		(get_au1000_speed()/1000) /
-		((int)(inl(SYS_POWERCTRL)&0x03) + 2);
+		((int)(au_readl(SYS_POWERCTRL)&0x03) + 2);
 
-	static_cfg0 = inl(MEM_STCFG0);
+	static_cfg0 = au_readl(MEM_STCFG0);
 
 	if (static_cfg0 & (1<<11))
 		lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/dbg_io.c linux-2.4.20-pre7/arch/mips/au1000/common/dbg_io.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/dbg_io.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/dbg_io.c	Thu Sep 12 20:01:39 2002
@@ -53,8 +53,8 @@
 #define UART_MOD_CNTRL	0x100	/* Module Control */
 
 /* memory-mapped read/write of the port */
-#define UART16550_READ(y)    (readl(DEBUG_BASE + y) & 0xff)
-#define UART16550_WRITE(y,z) (writel(z&0xff, DEBUG_BASE + y))
+#define UART16550_READ(y)    (au_readl(DEBUG_BASE + y) & 0xff)
+#define UART16550_WRITE(y,z) (au_writel(z&0xff, DEBUG_BASE + y))
 
 extern unsigned long get_au1000_uart_baud_base(void);
 extern unsigned long cal_r4koff(void);
@@ -71,7 +71,7 @@
 	UART16550_WRITE(UART_IER, 0);
 
 	/* set up baud rate */
-	{ 
+	{
 		uint32 divisor;
 
 		/* set divisor */
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/dma.c linux-2.4.20-pre7/arch/mips/au1000/common/dma.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/dma.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/dma.c	Thu Sep 12 20:01:39 2002
@@ -77,23 +77,22 @@
 	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}
+	{UART0_ADDR + UART_TX, 0},
+	{UART0_ADDR + UART_RX, 0},
+	{0, 0},
+	{0, 0},
+	{AC97C_DATA, DMA_DW16 },          // coherent
+	{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
+	{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}
 };
 
 
@@ -105,9 +104,8 @@
 
 	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);
+			len += sprintf(buf + len, "%2d: %s\n",
+				       i, chan->dev_str);
 		}
 	}
 
@@ -134,28 +132,32 @@
 
 	printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
 	printk(KERN_INFO "  mode = 0x%08x\n",
-	       inl(chan->io + DMA_MODE_SET));
+	       au_readl(chan->io + DMA_MODE_SET));
 	printk(KERN_INFO "  addr = 0x%08x\n",
-	       inl(chan->io + DMA_PERIPHERAL_ADDR));
+	       au_readl(chan->io + DMA_PERIPHERAL_ADDR));
 	printk(KERN_INFO "  start0 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER0_START));
+	       au_readl(chan->io + DMA_BUFFER0_START));
 	printk(KERN_INFO "  start1 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER1_START));
+	       au_readl(chan->io + DMA_BUFFER1_START));
 	printk(KERN_INFO "  count0 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER0_COUNT));
+	       au_readl(chan->io + DMA_BUFFER0_COUNT));
 	printk(KERN_INFO "  count1 = 0x%08x\n",
-	       inl(chan->io + DMA_BUFFER1_COUNT));
+	       au_readl(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.
+ * Requests the DMA done IRQ if irqhandler != NULL.
  */
-int request_au1000_dma(int dev_id, const char *dev_str)
+int request_au1000_dma(int dev_id, const char *dev_str,
+		       void (*irqhandler)(int, void *, struct pt_regs *),
+		       unsigned long irqflags,
+		       void *irq_dev_id)
 {
 	struct dma_chan *chan;
-	int i;
+	int i, ret;
 
 	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
 		return -EINVAL;
@@ -169,14 +171,30 @@
 
 	chan = &au1000_dma_table[i];
 
+	if (irqhandler) {
+		chan->irq = AU1000_DMA_INT_BASE + i;
+		chan->irq_dev = irq_dev_id;
+		if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+				       dev_str, chan->irq_dev))) {
+			chan->irq = 0;
+			chan->irq_dev = NULL;
+			return ret;
+		}
+	} else {
+		chan->irq = 0;
+		chan->irq_dev = NULL;
+	}
+
 	// 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;
 
+	/* initialize the channel before returning */
+	init_dma(i);
+
 	return i;
 }
 
@@ -190,6 +208,10 @@
 	}
 
 	disable_dma(dmanr);
+	if (chan->irq)
+		free_irq(chan->irq, chan->irq_dev);
 
+	chan->irq = 0;
+	chan->irq_dev = NULL;
 	chan->dev_id = -1;
-}				/* free_dma */
+}
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/int-handler.S linux-2.4.20-pre7/arch/mips/au1000/common/int-handler.S
--- linux-2.4.20-pre6/arch/mips/au1000/common/int-handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/int-handler.S	Thu Sep 12 20:01:39 2002
@@ -9,7 +9,6 @@
  * 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>
@@ -40,30 +39,30 @@
 
 1:
 	andi	a0, t0, CAUSEF_IP2	# Interrupt Controller 0, Request 0
-	beq	a0, zero, 2f	        
-	move	a0,sp  
+	beq	a0, zero, 2f
+	move	a0,sp
 	jal	intc0_req0_irqdispatch
 	j	ret_from_irq
 2:
 	andi	a0, t0, CAUSEF_IP3	# Interrupt Controller 0, Request 1
-	beq	a0, zero, 3f	       
-	move	a0,sp  
+	beq	a0, zero, 3f
+	move	a0,sp
 	jal	intc0_req1_irqdispatch
 	j	ret_from_irq
 3:
 	andi	a0, t0, CAUSEF_IP4	# Interrupt Controller 1, Request 0
-	beq	a0, zero, 4f	       
-	move	a0,sp  
+	beq	a0, zero, 4f
+	move	a0,sp
 	jal	intc1_req0_irqdispatch
 	j	ret_from_irq
 4:
 	andi	a0, t0, CAUSEF_IP5	# Interrupt Controller 1, Request 1
-	beq	a0, zero, 5f	       
-	move	a0, sp  
+	beq	a0, zero, 5f
+	move	a0, sp
 	jal	intc1_req1_irqdispatch
 	j	ret_from_irq
 
-5:	
+5:
 	move	a0, sp
 	j	spurious_interrupt
 END(au1000_IRQ)
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/irq.c linux-2.4.20-pre7/arch/mips/au1000/common/irq.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/irq.c	Thu Sep 12 20:01:39 2002
@@ -51,6 +51,8 @@
 #include <asm/pb1000.h>
 #elif defined(CONFIG_MIPS_PB1500)
 #include <asm/pb1500.h>
+#elif defined(CONFIG_MIPS_PB1100)
+#include <asm/pb1100.h>
 #else
 #error unsupported alchemy board
 #endif
@@ -103,86 +105,86 @@
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
 		switch (type) {
 			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG0SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
 				break;
 			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1SET);
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
 				break;
 			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				outl(1<<(irq_nr-32), IC1_CFG2SET);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG0SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
 				break;
 			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				outl(1<<(irq_nr-32), IC1_CFG2SET);
-				outl(1<<(irq_nr-32), IC1_CFG1SET);
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
 				break;
 			case INTC_INT_DISABLED: /* 0:0:0 */
-				outl(1<<(irq_nr-32), IC1_CFG0CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(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-32), IC1_CFG0CLR);
-				outl(1<<(irq_nr-32), IC1_CFG1CLR);
-				outl(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
 				return;
 		}
 		if (int_req) /* assign to interrupt request 1 */
-			outl(1<<(irq_nr-32), IC1_ASSIGNCLR);
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
 		else	     /* assign to interrupt request 0 */
-			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);
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
+		au_writel(1<<(irq_nr-32), IC1_SRCSET);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
 	}
 	else {
 		switch (type) {
 			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				outl(1<<irq_nr, IC0_CFG2CLR);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG0SET);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
 				break;
 			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				outl(1<<irq_nr, IC0_CFG2CLR);
-				outl(1<<irq_nr, IC0_CFG1SET);
-				outl(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
 				break;
 			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				outl(1<<irq_nr, IC0_CFG2SET);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG0SET);
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
 				break;
 			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				outl(1<<irq_nr, IC0_CFG2SET);
-				outl(1<<irq_nr, IC0_CFG1SET);
-				outl(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
 				break;
 			case INTC_INT_DISABLED: /* 0:0:0 */
-				outl(1<<irq_nr, IC0_CFG0CLR);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(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, IC0_CFG0CLR);
-				outl(1<<irq_nr, IC0_CFG1CLR);
-				outl(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
 				return;
 		}
 		if (int_req) /* assign to interrupt request 1 */
-			outl(1<<irq_nr, IC0_ASSIGNCLR);
+			au_writel(1<<irq_nr, IC0_ASSIGNCLR);
 		else	     /* assign to interrupt request 0 */
-			outl(1<<irq_nr, IC0_ASSIGNSET);
-		outl(1<<irq_nr, IC0_SRCSET);
-		outl(1<<irq_nr, IC0_MASKCLR);
-		outl(1<<irq_nr, IC0_WAKECLR);
+			au_writel(1<<irq_nr, IC0_ASSIGNSET);
+		au_writel(1<<irq_nr, IC0_SRCSET);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
 	}
 	au_sync();
 }
@@ -191,7 +193,7 @@
 static unsigned int startup_irq(unsigned int irq_nr)
 {
 	local_enable_irq(irq_nr);
-	return 0; 
+	return 0;
 }
 
 
@@ -205,12 +207,12 @@
 inline void local_enable_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_MASKSET);
-		outl(1<<(irq_nr-32), IC1_WAKESET);
+		au_writel(1<<(irq_nr-32), IC1_MASKSET);
+		au_writel(1<<(irq_nr-32), IC1_WAKESET);
 	}
 	else {
-		outl(1<<irq_nr, IC0_MASKSET);
-		outl(1<<irq_nr, IC0_WAKESET);
+		au_writel(1<<irq_nr, IC0_MASKSET);
+		au_writel(1<<irq_nr, IC0_WAKESET);
 	}
 	au_sync();
 }
@@ -219,12 +221,12 @@
 inline void local_disable_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
-		outl(1<<(irq_nr-32), IC1_WAKECLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
 	}
 	else {
-		outl(1<<irq_nr, IC0_MASKCLR);
-		outl(1<<irq_nr, IC0_WAKECLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
 	}
 	au_sync();
 }
@@ -233,12 +235,12 @@
 static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_RISINGCLR);
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
 	}
 	else {
-		outl(1<<irq_nr, IC0_RISINGCLR);
-		outl(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_RISINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
 	}
 	au_sync();
 }
@@ -247,12 +249,12 @@
 static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
 {
 	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		outl(1<<(irq_nr-32), IC1_FALLINGCLR);
-		outl(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
 	}
 	else {
-		outl(1<<irq_nr, IC0_FALLINGCLR);
-		outl(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_FALLINGCLR);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
 	}
 	au_sync();
 }
@@ -265,7 +267,7 @@
 	au_sync();
 #if defined(CONFIG_MIPS_PB1000)
 	if (irq_nr == AU1000_GPIO_15) {
-		writew(0x8000, PB1000_MDR); /* ack int */
+		au_writel(0x8000, PB1000_MDR); /* ack int */
 		au_sync();
 	}
 #endif
@@ -279,12 +281,12 @@
 		local_enable_irq(irq_nr);
 	}
 	else {
-		printk("warning: end_irq %d did not enable (%x)\n", 
+		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_writel(0x4000, PB1000_MDR); /* enable int */
 		au_sync();
 	}
 #endif
@@ -297,13 +299,13 @@
 	save_and_cli(flags);
 
 	if (controller) {
-		mask = readl(IC1_MASKSET);
+		mask = au_readl(IC1_MASKSET);
 		for (i=32; i<64; i++) {
 			local_disable_irq(i);
 		}
 	}
 	else {
-		mask = readl(IC0_MASKSET);
+		mask = au_readl(IC0_MASKSET);
 		for (i=0; i<32; i++) {
 			local_disable_irq(i);
 		}
@@ -327,9 +329,9 @@
 		}
 	}
 	if (controller)
-		new_mask = readl(IC1_MASKSET);
+		new_mask = au_readl(IC1_MASKSET);
 	else
-		new_mask = readl(IC0_MASKSET);
+		new_mask = au_readl(IC0_MASKSET);
 
 	restore_flags(flags);
 }
@@ -390,10 +392,6 @@
 
 	init_generic_irq();
 
-	/* override the generic vec0 handler */
-	memcpy((void *)KSEG0, &except_vec0_au1000, 0x80);
-	flush_icache_range(KSEG0, KSEG0 + 0x200);
-	
 	for (i = 0; i <= AU1000_MAX_INTR; i++) {
 		switch (i) {
 			case AU1000_UART0_INT:
@@ -406,6 +404,12 @@
 			case AU1000_SSI1_INT:
 #endif
 
+#ifdef CONFIG_MIPS_PB1100
+			case AU1000_UART1_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:
@@ -419,9 +423,14 @@
 			case AU1000_IRDA_RX_INT:
 
 			case AU1000_MAC0_DMA_INT:
+#ifdef CONFIG_MIPS_PB1000
 			case AU1000_MAC1_DMA_INT:
-
+#endif
+#ifdef CONFIG_MIPS_PB1500
+			case AU1000_MAC1_DMA_INT:
+#endif
 			case AU1500_GPIO_204:
+
 				setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
 				irq_desc[i].handler = &level_irq_type;
 				break;
@@ -441,16 +450,24 @@
 			case AU1500_GPIO_205:
 			case AU1500_GPIO_207:
 #endif
+
+#ifdef CONFIG_MIPS_PB1100
+			case AU1000_GPIO_9: // PCMCIA Card Fully_Interted#
+			case AU1000_GPIO_10: // PCMCIA_STSCHG#
+			case AU1000_GPIO_11: // PCMCIA_IRQ#
+			case AU1000_GPIO_13: // DC_IRQ#
+			case AU1000_GPIO_23: // 2-wire SCL
+#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_USB_DEV_SUS_INT:
+		        case AU1000_USB_DEV_REQ_INT:
 			case AU1000_RTC_INT:
 			case AU1000_RTC_MATCH0_INT:
 			case AU1000_RTC_MATCH1_INT:
@@ -478,7 +495,7 @@
 	/* If local serial I/O used for debug port, enter kgdb at once */
 	puts("Waiting for kgdb to connect...");
 	set_debug_traps();
-	breakpoint(); 
+	breakpoint();
 #endif
 }
 
@@ -494,10 +511,21 @@
 	int irq = 0, i;
 	static unsigned long intc0_req0 = 0;
 
-	intc0_req0 |= inl(IC0_REQ0INT);
+	intc0_req0 |= au_readl(IC0_REQ0INT);
 
 	if (!intc0_req0) return;
 
+	/*
+	 * Because of the tight timing of SETUP token to reply
+	 * transactions, the USB devices-side packet complete
+	 * interrupt needs the highest priority.
+	 */
+	if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
+		intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
+		do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
+		return;
+	}
+
 	for (i=0; i<32; i++) {
 		if ((intc0_req0 & (1<<i))) {
 			intc0_req0 &= ~(1<<i);
@@ -514,7 +542,7 @@
 	int irq = 0, i;
 	static unsigned long intc0_req1 = 0;
 
-	intc0_req1 = inl(IC0_REQ1INT);
+	intc0_req1 = au_readl(IC0_REQ1INT);
 
 	if (!intc0_req1) return;
 
@@ -527,7 +555,7 @@
 				counter0_irq(irq, NULL, regs);
 				local_enable_irq(irq);
 			}
-			else 
+			else
 #endif
 			{
 				do_IRQ(irq, regs);
@@ -550,20 +578,20 @@
 	volatile unsigned short levels, mdr;
 	unsigned char ide_status;
 
-	intc1_req0 |= inl(IC1_REQ0INT);
+	intc1_req0 |= au_readl(IC1_REQ0INT);
 
 	if (!intc1_req0) return;
 
-#ifdef CONFIG_MIPS_PB1000
-	writew(1, CPLD_AUX0); /* debug led 0 */
+#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
+	au_writel(1, CPLD_AUX0); /* debug led 0 */
 #endif
 	for (i=0; i<32; i++) {
 		if ((intc1_req0 & (1<<i))) {
 			intc1_req0 &= ~(1<<i);
-#ifdef CONFIG_MIPS_PB1000
-			writew(2, CPLD_AUX0); /* turn on debug led 1  */
+#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
+			au_writel(2, CPLD_AUX0); /* turn on debug led 1  */
 			do_IRQ(irq+32, regs);
-			writew(0, CPLD_AUX0); /* turn off debug led 1 */
+			au_writel(0, CPLD_AUX0); /* turn off debug led 1 */
 #else
 			do_IRQ(irq+32, regs);
 #endif
@@ -571,8 +599,8 @@
 		}
 		irq++;
 	}
-#ifdef CONFIG_MIPS_PB1000
-	writew(0, CPLD_AUX0);
+#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ)
+	au_writel(0, CPLD_AUX0);
 #endif
 }
 
@@ -582,7 +610,7 @@
 	int irq = 0, i;
 	static unsigned long intc1_req1 = 0;
 
-	intc1_req1 |= inl(IC1_REQ1INT);
+	intc1_req1 |= au_readl(IC1_REQ1INT);
 
 	if (!intc1_req1) return;
 
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/power.c linux-2.4.20-pre7/arch/mips/au1000/common/power.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/power.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/power.c	Thu Sep 12 20:01:39 2002
@@ -29,7 +29,7 @@
  *  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/pm.h>
 #include <linux/slab.h>
@@ -49,7 +49,7 @@
 #  define DPRINTK(fmt, args...)
 #endif
 
-inline void au1_wait(void);
+extern void au1k_wait(void);
 static void calibrate_delay(void);
 
 extern void set_au1000_speed(unsigned int new_freq);
@@ -81,16 +81,16 @@
 
 	flush_cache_all();
 	/* pin 6 is gpio */
-	writel(readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
+	au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
 
 	/* gpio 6 can cause a wake up event */
-	wakeup = readl(SYS_WAKEMSK);
+	wakeup = au_readl(SYS_WAKEMSK);
 	wakeup &= ~(1 << 8);	/* turn off match20 wakeup */
 	wakeup |= 1 << 6;	/* turn on gpio 6 wakeup   */
-	writel(wakeup, SYS_WAKEMSK);
+	au_writel(wakeup, SYS_WAKEMSK);
 
-	writel(1, SYS_WAKESRC);	/* clear cause */
-	writel(1, SYS_SLPPWR);	/* prepare to sleep */
+	au_writel(1, SYS_WAKESRC);	/* clear cause */
+	au_writel(1, SYS_SLPPWR);	/* prepare to sleep */
 
 	__asm__("la $4, 1f\n\t"
 		"lui $5, 0xb190\n\t"
@@ -138,7 +138,7 @@
 		if (retval)
 			return retval;
 		suspend_mode = 1;
-		au1_wait();
+		au1k_wait();
 		retval = pm_send_all(PM_RESUME, (void *) 0);
 	}
 	return retval;
@@ -194,22 +194,22 @@
 		set_au1000_speed(new_cpu_freq);
 		set_au1000_uart_baud_base(new_baud_base);
 
-		old_refresh = readl(MEM_SDREFCFG) & 0x1ffffff;
+		old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
 		new_refresh =
 		    ((old_refresh * new_cpu_freq) /
-		     old_cpu_freq) | (readl(MEM_SDREFCFG) & ~0x1ffffff);
+		     old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
 
-		writel(pll, SYS_CPUPLL);
+		au_writel(pll, SYS_CPUPLL);
 		au_sync_delay(1);
-		writel(new_refresh, MEM_SDREFCFG);
+		au_writel(new_refresh, MEM_SDREFCFG);
 		au_sync_delay(1);
 
 		for (i = 0; i < 4; i++) {
-			if (readl
+			if (au_readl
 			    (UART_BASE + UART_MOD_CNTRL +
 			     i * 0x00100000) == 3) {
 				old_clk =
-				    readl(UART_BASE + UART_CLK +
+				    au_readl(UART_BASE + UART_CLK +
 					  i * 0x00100000);
 				// baud_rate = baud_base/clk
 				baud_rate = old_baud_base / old_clk;
@@ -231,7 +231,7 @@
 					(baud_rate = 9600);
 				// new_clk = new_baud_base/baud_rate
 				new_clk = new_baud_base / baud_rate;
-				writel(new_clk,
+				au_writel(new_clk,
 				       UART_BASE + UART_CLK +
 				       i * 0x00100000);
 				au_sync_delay(10);
@@ -246,7 +246,7 @@
 	 */
 	intc0_mask = save_local_and_disable(0);
 	intc1_mask = save_local_and_disable(1);
-	local_enable_irq(AU1000_TOY_MATCH2);
+	local_enable_irq(AU1000_TOY_MATCH2_INT);
 	restore_flags(flags);
 	calibrate_delay();
 	restore_local_and_enable(0, intc0_mask);
@@ -278,13 +278,6 @@
 
 __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
@@ -330,12 +323,4 @@
 	}
 }
 
-
-#else				/* CONFIG_PM */
-
-void au1_wait(void)
-{
-	__asm__("nop\n\t" "nop\n\t");
-}
-
 #endif				/* CONFIG_PM */
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/prom.c linux-2.4.20-pre7/arch/mips/au1000/common/prom.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/prom.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/prom.c	Thu Sep 12 20:01:39 2002
@@ -8,7 +8,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/xx files.
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -125,7 +125,7 @@
 		ea[i] = num;
 	}
 }
- 
+
 int get_ethernet_addr(char *ethernet_addr)
 {
 	int i;
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/reset.c linux-2.4.20-pre7/arch/mips/au1000/common/reset.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/reset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/reset.c	Thu Sep 12 20:01:39 2002
@@ -27,7 +27,7 @@
  *  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/sched.h>
 #include <linux/mm.h>
 #include <asm/io.h>
@@ -35,6 +35,7 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
+#include <asm/au1000.h>
 
 extern int au_sleep(void);
 
@@ -47,40 +48,60 @@
 	switch (prid & 0xFF000000)
 	{
 	case 0x00000000: /* Au1000 */
-		outl(0x02, 0xb0000010); /* ac97_enable */
-		outl(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(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 */
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb0300040); /* ir_enable */
+		au_writel(0x00, 0xb0520000); /* macen0 */
+		au_writel(0x00, 0xb0520004); /* macen1 */
+		au_writel(0x00, 0xb1000008); /* i2s_enable  */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1300100); /* uart2_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x02, 0xb1600100); /* ssi0_enable */
+		au_writel(0x02, 0xb1680100); /* ssi1_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
 		break;
 	case 0x01000000: /* Au1500 */
-		outl(0x02, 0xb0000010); /* ac97_enable */
-		outl(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */
+		asm("sync");
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb1520000); /* macen0 */
+		au_writel(0x00, 0xb1520004); /* macen1 */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
+	case 0x02000000: /* Au1100 */
+		au_writel(0x02, 0xb0000010); /* ac97_enable */
+		au_writel(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 */
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb0300040); /* ir_enable */
+		au_writel(0x00, 0xb0520000); /* macen0 */
+		au_writel(0x00, 0xb1000008); /* i2s_enable  */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x02, 0xb1600100); /* ssi0_enable */
+		au_writel(0x02, 0xb1680100); /* ssi1_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
 
 	default:
 		break;
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/rtc.c linux-2.4.20-pre7/arch/mips/au1000/common/rtc.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/rtc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/rtc.c	Thu Sep 12 20:01:39 2002
@@ -9,19 +9,20 @@
  */
 #include <linux/mc146818rtc.h>
 #include <asm/io.h>
+#include <asm/au1000.h>
 
 #define PB1500_RTC_ADDR 0xAC000000
 
-static unsigned char std_rtc_read_data(unsigned long addr)
+unsigned char std_rtc_read_data(unsigned long offset)
 {
-	addr <<= 2;
-	return readb(addr + PB1500_RTC_ADDR);
+	offset <<= 2;
+	return (u8)(au_readl(offset + PB1500_RTC_ADDR) & 0xff);
 }
 
-static void std_rtc_write_data(unsigned char data, unsigned long addr)
+static void std_rtc_write_data(unsigned char data, unsigned long offset)
 {
-	addr <<= 2;
-	writeb(data, addr + PB1500_RTC_ADDR);
+	offset <<= 2;
+	au_writel(data, offset + PB1500_RTC_ADDR);
 }
 
 static int std_rtc_bcd_mode(void)
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/serial.c linux-2.4.20-pre7/arch/mips/au1000/common/serial.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/serial.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/serial.c	Thu Sep 12 20:01:39 2002
@@ -10,7 +10,7 @@
  *  Derived almost entirely from drivers/char/serial.c:
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 
+ *  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,
  * 		1998, 1999  Theodore Ts'o
  *
  *  This program is free software; you can redistribute  it and/or modify it
@@ -63,7 +63,7 @@
 
 #define RS_STROBE_TIME (10*HZ)
 #define RS_ISR_PASS_LIMIT 256
-  
+
 /*
  * End of serial driver configuration section.
  */
@@ -166,10 +166,10 @@
  * UART
  */
 static struct serial_uart_config uart_config[] = {
-	{ "unknown", 1, 0 }, 
-	{ "8250", 1, 0 }, 
-	{ "16450", 1, 0 }, 
-	{ "16550", 1, 0 }, 
+	{ "unknown", 1, 0 },
+	{ "8250", 1, 0 },
+	{ "16450", 1, 0 },
+	{ "16550", 1, 0 },
 	{ 0, 0}
 };
 
@@ -238,15 +238,14 @@
 	return 0;
 }
 
-
 static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
 {
-	return (inl(info->port+offset) & 0xffff);
+	return (au_readl(info->port+offset) & 0xffff);
 }
 
 static _INLINE_ void serial_out(struct async_struct *info, int offset, int value)
 {
-	outl(value & 0xffff, info->port+offset);
+	au_writel(value & 0xffff, info->port+offset);
 }
 
 
@@ -275,7 +274,7 @@
 
 	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;
@@ -288,10 +287,10 @@
 {
 	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
@@ -314,7 +313,7 @@
  * 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.
@@ -350,7 +349,7 @@
 			goto ignore_char;
 		*tty->flip.char_buf_ptr = ch;
 		icount->rx++;
-		
+
 #ifdef SERIAL_DEBUG_INTR
 		printk("DR%02x:%02x...", ch, *status);
 #endif
@@ -468,7 +467,7 @@
 		serial_out(info, UART_IER, info->IER);
 		return;
 	}
-	
+
 	count = info->xmit_fifo_size;
 	do {
 		serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
@@ -477,7 +476,7 @@
 		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)
@@ -499,7 +498,7 @@
 {
 	int	status;
 	struct	async_icount *icount;
-	
+
 	status = serial_in(info, UART_MSR);
 
 	if (status & UART_MSR_ANY_DELTA) {
@@ -526,7 +525,7 @@
 #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
 		printk("ttys%d CD now %s...", info->line,
 		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif		
+#endif
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
 		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
@@ -573,7 +572,7 @@
 	int status;
 	int pass_counter = 0;
 	struct async_struct * info;
-	
+
 #ifdef SERIAL_DEBUG_INTR
 	printk("rs_interrupt_single(%d)...", irq);
 #endif
@@ -630,7 +629,7 @@
 {
 	struct async_struct	*info = (struct async_struct *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -750,8 +749,8 @@
 		info->xmit.buf = (unsigned char *) page;
 
 
-	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
-		outl(3, UART_MOD_CNTRL + state->port);
+	if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) {
+		au_writel(3, UART_MOD_CNTRL + state->port);
 		au_sync_delay(10);
 	}
 #ifdef SERIAL_DEBUG_OPEN
@@ -794,7 +793,7 @@
 			retval = -ENODEV;
 		goto errout;
 	}
-	
+
 	/*
 	 * Allocate the IRQ if necessary
 	 */
@@ -806,7 +805,7 @@
 		if (IRQ_ports[state->irq]) {
 			retval = -EBUSY;
 			goto errout;
-		} else 
+		} else
 			handler = rs_interrupt_single;
 
 		retval = request_irq(state->irq, handler, SA_SHIRQ,
@@ -833,7 +832,7 @@
 	figure_IRQ_timeout(state->irq);
 
 	/*
-	 * Now, initialize the UART 
+	 * Now, initialize the UART
 	 */
 	serial_outp(info, UART_LCR, UART_LCR_WLEN8);
 
@@ -846,13 +845,13 @@
 	}
 	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
 	serial_outp(info, UART_MCR, info->MCR);
-	
+
 	/*
 	 * Finally, enable interrupts
 	 */
 	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
-	
+
 
 	/*
 	 * And clear the interrupt registers again for luck.
@@ -884,7 +883,7 @@
 		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
 			info->tty->alt_speed = 460800;
 	}
-	
+
 	/*
 	 * and set the speed of the serial port
 	 */
@@ -893,7 +892,7 @@
 	info->flags |= ASYNC_INITIALIZED;
 	restore_flags(flags);
 	return 0;
-	
+
 errout:
 	restore_flags(flags);
 	return retval;
@@ -918,7 +917,7 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       state->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
 
 	/*
@@ -926,7 +925,7 @@
 	 * here so the queue might never be waken up
 	 */
 	wake_up_interruptible(&info->delta_msr_wait);
-	
+
 	/*
 	 * First unlink the serial port from the IRQ chain...
 	 */
@@ -937,7 +936,7 @@
 	else
 		IRQ_ports[state->irq] = info->next_port;
 	figure_IRQ_timeout(state->irq);
-	
+
 	/*
 	 * Free the IRQ, if necessary
 	 */
@@ -949,7 +948,7 @@
 			retval = request_irq(state->irq, rs_interrupt_single,
 					     SA_SHIRQ, "serial",
 					     &IRQ_ports[state->irq]);
-			
+
 			if (retval)
 				printk("serial shutdown: request_irq: error %d"
 				       "  Couldn't reacquire IRQ.\n", retval);
@@ -967,28 +966,28 @@
 	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
 		info->MCR &= ~UART_MCR_OUT2;
 	info->MCR |= ALPHA_KLUDGE_MCR; 		/* Don't ask */
-	
+
 	/* disable break condition */
 	serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
-	
+
 	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
 		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
 	serial_outp(info, UART_MCR, info->MCR);
 
-	/* disable FIFO's */	
+	/* disable FIFO's */
 	serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
 				     UART_FCR_CLEAR_RCVR |
 				     UART_FCR_CLEAR_XMIT));
 	serial_outp(info, UART_FCR, 0);
 
 	(void)serial_in(info, UART_RX);    /* read data port to reset things */
-	
+
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
 	info->flags &= ~ASYNC_INITIALIZED;
 #ifndef CONFIG_REMOTE_DEBUG
-	outl(0, UART_MOD_CNTRL + state->port);
+	au_writel(0, UART_MOD_CNTRL + state->port);
 	au_sync_delay(10);
 #endif
 	restore_flags(flags);
@@ -1076,7 +1075,7 @@
 	/* As a last resort, if the quotient is zero, default to 9600 bps */
 	if (!quot)
 		quot = baud_base / 9600;
-	
+
 	info->quot = quot;
 	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
 	info->timeout += HZ/50;		/* Add .02 seconds of slop */
@@ -1088,7 +1087,7 @@
 		else
 			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8;
 	}
-	
+
 	/* CTS flow control flag and modem status interrupts */
 	info->IER &= ~UART_IER_MSI;
 	if (info->flags & ASYNC_HARDPPS_CD)
@@ -1116,7 +1115,7 @@
 		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
 	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
 		info->read_status_mask |= UART_LSR_BI;
-	
+
 	/*
 	 * Characters to ignore
 	 */
@@ -1126,7 +1125,7 @@
 	if (I_IGNBRK(info->tty)) {
 		info->ignore_status_mask |= UART_LSR_BI;
 		/*
-		 * If we're ignore parity and break indicators, ignore 
+		 * If we're ignore parity and break indicators, ignore
 		 * overruns too.  (For real raw support).
 		 */
 		if (I_IGNPAR(info->tty))
@@ -1173,7 +1172,7 @@
 {
 	struct async_struct *info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
 		return;
 
@@ -1195,7 +1194,7 @@
 	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;
 
@@ -1278,7 +1277,7 @@
 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);
@@ -1288,7 +1287,7 @@
 {
 	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();
@@ -1325,7 +1324,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1336,14 +1335,14 @@
 	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));
 
@@ -1361,14 +1360,14 @@
 	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;
@@ -1393,7 +1392,7 @@
 {
 	struct serial_struct tmp;
 	struct serial_state *state = info->state;
-   
+
 	if (!retinfo)
 		return -EFAULT;
 	memset(&tmp, 0, sizeof(tmp));
@@ -1439,7 +1438,7 @@
 	change_irq = new_serial.irq != state->irq;
 	change_port = (new_port != ((int) state->port)) ||
 		(new_serial.hub6 != state->hub6);
-  
+
 	if (!capable(CAP_SYS_ADMIN)) {
 		if (change_irq || change_port ||
 		    (new_serial.baud_base != state->baud_base) ||
@@ -1459,7 +1458,7 @@
 
 	new_serial.irq = irq_cannonicalize(new_serial.irq);
 
-	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
 	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
 	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
 	    (new_serial.type == PORT_STARTECH)) {
@@ -1522,7 +1521,7 @@
 			request_region(state->port,8,"serial(set)");
 	}
 
-	
+
 check_and_exit:
 	if (!state->port || !state->type)
 		return 0;
@@ -1555,7 +1554,7 @@
  * 	    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. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct async_struct * info, unsigned int *value)
 {
@@ -1574,7 +1573,7 @@
 	 * avoid a race condition (depending on when the transmit
 	 * interrupt happens).
 	 */
-	if (info->x_char || 
+	if (info->x_char ||
 	    ((CIRC_CNT(info->xmit.head, info->xmit.tail,
 		       SERIAL_XMIT_SIZE) > 0) &&
 	     !info->tty->stopped && !info->tty->hw_stopped))
@@ -1622,7 +1621,7 @@
 		return -EFAULT;
 
 	switch (cmd) {
-	case TIOCMBIS: 
+	case TIOCMBIS:
 		if (arg & TIOCM_RTS)
 			info->MCR |= UART_MCR_RTS;
 		if (arg & TIOCM_DTR)
@@ -1679,13 +1678,13 @@
 static int do_autoconfig(struct async_struct * info)
 {
 	int retval;
-	
+
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-	
+
 	if (info->state->count > 1)
 		return -EBUSY;
-	
+
 	shutdown(info);
 
 	autoconfig(info->state);
@@ -1702,7 +1701,7 @@
 {
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_break"))
 		return;
 
@@ -1725,7 +1724,7 @@
 	struct async_icount cprev, cnow;	/* kernel counter temps */
 	struct serial_icounter_struct icount;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
 		return -ENODEV;
 
@@ -1735,7 +1734,7 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
 		case TIOCMGET:
 			return get_modem_info(info, (unsigned int *) arg);
@@ -1760,8 +1759,8 @@
 					 info, sizeof(struct async_struct)))
 				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
@@ -1784,7 +1783,7 @@
 				save_flags(flags); cli();
 				cnow = info->state->icount; /* atomic copy */
 				restore_flags(flags);
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				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)) ||
@@ -1797,7 +1796,7 @@
 			}
 			/* NOTREACHED */
 
-		/* 
+		/*
 		 * 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
@@ -1818,7 +1817,7 @@
 			icount.parity = cnow.parity;
 			icount.brk = cnow.brk;
 			icount.buf_overrun = cnow.buf_overrun;
-			
+
 			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
 				return -EFAULT;
 			return 0;
@@ -1839,9 +1838,9 @@
 	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(tty->termios->c_iflag)
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
@@ -1855,12 +1854,12 @@
 		serial_out(info, UART_MCR, info->MCR);
 		restore_flags(flags);
 	}
-	
+
 	/* Handle transition away from B0 status */
 	if (!(old_termios->c_cflag & CBAUD) &&
 	    (cflag & CBAUD)) {
 		info->MCR |= UART_MCR_DTR;
-		if (!(tty->termios->c_cflag & CRTSCTS) || 
+		if (!(tty->termios->c_cflag & CRTSCTS) ||
 		    !test_bit(TTY_THROTTLED, &tty->flags)) {
 			info->MCR |= UART_MCR_RTS;
 		}
@@ -1868,7 +1867,7 @@
 		serial_out(info, UART_MCR, info->MCR);
 		restore_flags(flags);
 	}
-	
+
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1880,7 +1879,7 @@
 /*
  * ------------------------------------------------------------
  * 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
@@ -1897,16 +1896,16 @@
 		return;
 
 	state = info->state;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		DBG_CNT("before DEC-hung");
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 		return;
 	}
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
 #endif
@@ -1944,7 +1943,7 @@
 	if (info->flags & ASYNC_CALLOUT_ACTIVE)
 		info->state->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1996,7 +1995,7 @@
 	struct async_struct * info = (struct async_struct *)tty->driver_data;
 	unsigned long orig_jiffies, char_time;
 	int lsr;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
 		return;
 
@@ -2011,7 +2010,7 @@
 	 * 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.
 	 */
@@ -2060,12 +2059,12 @@
 {
 	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);
 	if (info->flags & ASYNC_CLOSING)
 		return;
@@ -2125,7 +2124,7 @@
 		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.
@@ -2145,7 +2144,7 @@
 		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
@@ -2181,7 +2180,7 @@
 			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -2283,7 +2282,7 @@
 	tty->driver_data = info;
 	info->tty = tty;
 	if (serial_paranoia_check(info, tty->device, "rs_open")) {
-		MOD_DEC_USE_COUNT;		
+		MOD_DEC_USE_COUNT;
 		return -ENODEV;
 	}
 
@@ -2344,7 +2343,7 @@
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->state->normal_termios;
-		else 
+		else
 			*tty->termios = info->state->callout_termios;
 		change_speed(info, 0);
 	}
@@ -2376,7 +2375,7 @@
 	unsigned long flags;
 
 	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
-		      state->line, uart_config[state->type].name, 
+		      state->line, uart_config[state->type].name,
 		      state->port, state->irq);
 
 	if (!state->port || (state->type == PORT_UNKNOWN)) {
@@ -2399,7 +2398,7 @@
 	save_flags(flags); cli();
 	status = serial_in(info, UART_MSR);
 	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
-	restore_flags(flags); 
+	restore_flags(flags);
 
 	stat_buf[0] = 0;
 	stat_buf[1] = 0;
@@ -2426,12 +2425,12 @@
 
 	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);	
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
 
 	if (state->icount.overrun)
 		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
@@ -2511,15 +2510,15 @@
 	printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
 	       state->port, (unsigned) state->iomem_base);
 #endif
-	
+
 	if (!CONFIGURED_SERIAL_PORT(state))
 		return;
 
-	if (inl(UART_MOD_CNTRL + state->port) != 0x3) {
-		outl(3, UART_MOD_CNTRL + state->port);
+	if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) {
+		au_writel(3, UART_MOD_CNTRL + state->port);
 		au_sync_delay(10);
 	}
-		
+
 	state->type = PORT_16550;
 	info = &scr_info;	/* This is just for serial_{in,out} */
 
@@ -2548,11 +2547,6 @@
 	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);
 }
 
@@ -2595,7 +2589,7 @@
 	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 = "serial";
@@ -2637,7 +2631,7 @@
 	serial_driver.send_xchar = rs_send_xchar;
 	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.
@@ -2657,7 +2651,7 @@
 		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
 		panic("Couldn't register callout driver");
-	
+
 	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
 		state->baud_base = get_au1000_uart_baud_base();
 		state->magic = SSTATE_MAGIC;
@@ -2668,7 +2662,7 @@
 		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.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;
@@ -2705,7 +2699,7 @@
  * register_serial and unregister_serial allows for 16x50 serial ports to be
  * configured at run-time, to support PCMCIA modems.
  */
- 
+
 /**
  *	register_serial - configure a 16x50 serial port at runtime
  *	@req: request structure
@@ -2719,7 +2713,7 @@
  *
  *	On success the port is ready to use and the line number is returned.
  */
- 
+
 int register_serial(struct serial_struct *req)
 {
 	int i;
@@ -2784,7 +2778,7 @@
 	      state->iomem_base ? (unsigned long)state->iomem_base :
 	      state->port, state->irq, uart_config[state->type].name);
 	tty_register_devfs(&serial_driver, 0,
-			   serial_driver.minor_start + state->line); 
+			   serial_driver.minor_start + state->line);
 	tty_register_devfs(&callout_driver, 0,
 			   callout_driver.minor_start + state->line);
 	return state->line + SERIAL_DEV_OFFSET;
@@ -2819,7 +2813,7 @@
 	restore_flags(flags);
 }
 
-static void __exit rs_fini(void) 
+static void __exit rs_fini(void)
 {
 	unsigned long flags;
 	int e1, e2;
@@ -2834,7 +2828,7 @@
 		printk("serial: failed to unregister serial driver (%d)\n",
 		       e1);
 	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("serial: failed to unregister callout driver (%d)\n", 
+		printk("serial: failed to unregister callout driver (%d)\n",
 		       e2);
 	restore_flags(flags);
 
@@ -2882,7 +2876,7 @@
 
 		if (status & UART_LSR_BI)
 			lsr_break_flag = UART_LSR_BI;
-		
+
 		if (--tmout == 0)
 			break;
 	} while((status & BOTH_EMPTY) != BOTH_EMPTY);
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/time.c linux-2.4.20-pre7/arch/mips/au1000/common/time.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/time.c	Thu Sep 12 20:01:39 2002
@@ -1,5 +1,5 @@
 /*
- * 
+ *
  * Copyright (C) 2001 MontaVista Software, ppopov@mvista.com
  * Copied and modified Carsten Langgaard's time.c
  *
@@ -123,13 +123,13 @@
 	static int jiffie_drift = 0;
 
 	kstat.irqs[0][irq]++;
-	if (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
+	if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
 		/* should never happen! */
 		printk(KERN_WARNING "counter 0 w status eror\n");
 		return;
 	}
 
-	pc0 = inl(SYS_TOYREAD);
+	pc0 = au_readl(SYS_TOYREAD);
 	if (pc0 < last_match20) {
 		/* counter overflowed */
 		time_elapsed = (0xffffffff - last_match20) + pc0;
@@ -146,13 +146,13 @@
 	}
 
 	last_pc0 = pc0;
-	outl(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+	au_writel(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 */
@@ -160,9 +160,9 @@
 }
 #endif
 
-/* 
+/*
  * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
+ * register for each time tick.
  * Use the Programmable Counter 1 to do this.
  */
 unsigned long cal_r4koff(void)
@@ -176,27 +176,27 @@
 
 	save_and_cli(flags);
 
-	counter = inl(SYS_COUNTER_CNTRL);
-	outl(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
+	counter = au_readl(SYS_COUNTER_CNTRL);
+	au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
 
-	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);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+	au_writel(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
+	au_writel (0, SYS_TOYWRITE);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
 
-	start = inl(SYS_RTCREAD);
+	start = au_readl(SYS_RTCREAD);
 	start += 2;
 	/* wait for the beginning of a new tick */
-	while (inl(SYS_RTCREAD) < start);
+	while (au_readl(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(SYS_RTCREAD));
+	while (end > au_readl(SYS_RTCREAD));
 
 	count = read_32bit_cp0_register(CP0_COUNT);
 	cpu_speed = count * 2;
@@ -215,11 +215,11 @@
 	r4k_offset = cal_r4koff();
 	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
 
-	//est_freq = 2*r4k_offset*HZ;	
-	est_freq = r4k_offset*HZ;	
+	//est_freq = 2*r4k_offset*HZ;
+	est_freq = r4k_offset*HZ;
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	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
@@ -241,20 +241,20 @@
 	 * 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);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
+	au_writel(0, SYS_TOYWRITE);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
 
-	writel(readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
-	writel(~0, SYS_WAKESRC);
+	au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
+	au_writel(~0, SYS_WAKESRC);
 	au_sync();
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+	while (au_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);
+	last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
+	au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
 	au_sync();
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
 	startup_match20_interrupt();
 #endif
 
@@ -282,7 +282,7 @@
 	unsigned long pc0;
 	unsigned long offset;
 
-	pc0 = readl(SYS_TOYREAD);
+	pc0 = au_readl(SYS_TOYREAD);
 	if (pc0 < last_pc0) {
 		offset = 0xffffffff - last_pc0 + pc0;
 		printk("offset over: %x\n", (unsigned)offset);
@@ -291,8 +291,8 @@
 		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, 
+		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();
@@ -338,7 +338,7 @@
 		 "r" (quotient));
 
 	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
+ 	 * 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)
diff -urN linux-2.4.20-pre6/arch/mips/au1000/common/usbdev.c linux-2.4.20-pre7/arch/mips/au1000/common/usbdev.c
--- linux-2.4.20-pre6/arch/mips/au1000/common/usbdev.c	Thu Sep 12 20:01:30 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/common/usbdev.c	Thu Sep 12 20:01:39 2002
@@ -1,8 +1,8 @@
 /*
  * BRIEF MODULE DESCRIPTION
- *	Au1000 USB Device-Side Serial TTY Driver
+ *	Au1000 USB Device-Side (device layer)
  *
- * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2001-2002 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *		stevel@mvista.com or source@mvista.com
  *
@@ -37,9 +37,6 @@
 #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>
@@ -53,54 +50,30 @@
 #include <asm/mipsregs.h>
 #include <asm/au1000.h>
 #include <asm/au1000_dma.h>
+#include <asm/au1000_usbdev.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
+#ifdef DEBUG
+#undef VDEBUG
+#ifdef VDEBUG
+#define vdbg(fmt, arg...) printk(KERN_DEBUG __FILE__ ": " fmt "\n" , ## arg)
+#else
+#define vdbg(fmt, arg...) do {} while (0)
+#endif
+#else
+#define vdbg(fmt, arg...) do {} while (0)
+#endif
 
 #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);
+	SETUP_STAGE = 0,
+	DATA_STAGE,
+	STATUS_STAGE
+} ep0_stage_t;
 
 typedef struct {
 	int read_fifo;
@@ -110,184 +83,68 @@
 	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;
+	usbdev_pkt_t *head;
+	usbdev_pkt_t *tail;
 	int count;
 } pkt_list_t;
 
 typedef struct {
+	int active;
 	struct usb_endpoint_descriptor *desc;
 	endpoint_reg_t *reg;
-	// Only one of these are used, unless this is a control ep
+	/* Only one of these are used, unless this is the 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
+	unsigned int indma, outdma; /* DMA channel numbers for IN, OUT */
+	/* following are extracted from endpoint descriptor for easy access */
 	int max_pkt_size;
+	int type;
+	int direction;
+	/* WE assign endpoint addresses! */
+	int address;
 	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];
+static struct usb_dev {
+	endpoint_t ep[6];
+	ep0_stage_t ep0_stage;
+
+	struct usb_device_descriptor *   dev_desc;
+	struct usb_interface_descriptor* if_desc;
+	struct usb_config_descriptor *   conf_desc;
+	u8 *                             full_conf_desc;
+	struct usb_string_descriptor *   str_desc[6];
+
+	/* callback to function layer */
+	void (*func_cb)(usbdev_cb_type_t type, unsigned long arg,
+			void *cb_data);
+	void* cb_data;
 
-	struct usb_serial_port port[NUM_PORTS];
-
-	dev_state_t state;	// device state
+	usbdev_state_t state;	// device state
 	int suspended;		// suspended flag
 	int address;		// device address
 	int interface;
+	int num_ep;
 	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
-};
+} usbdev;
 
 
 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
+	{USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT },
+	{0},
+	// FIFO 2 is EP2, 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}
+	// FIFO 3 is EP3, IN
+	{    -1,     USBD_EP3WR, USBD_EP3CS,     -1,         USBD_EP3WRSTAT },
+	// FIFO 4 is EP4, OUT
+	{USBD_EP4RD,     -1,     USBD_EP4CS, USBD_EP4RDSTAT,     -1         },
+	// FIFO 5 is EP5, OUT
+	{USBD_EP5RD,     -1,     USBD_EP5CS, USBD_EP5RDSTAT,     -1         }
 };
 
 static struct {
@@ -297,172 +154,88 @@
 	{ 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_EP4_RX, "USBDev EP4 OUT" },
 	{ 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;
-}
+#define CONTROL_EP USB_ENDPOINT_XFER_CONTROL
+#define BULK_EP    USB_ENDPOINT_XFER_BULK
 
 static inline endpoint_t *
-epnum_to_ep(struct usb_serial* serial, int ep_num)
+epaddr_to_ep(struct usb_dev* dev, int ep_addr)
 {
-	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;
-	}
-
+	if (ep_addr >= 0 && ep_addr < 2)
+		return &dev->ep[0];
+	if (ep_addr < 6)
+		return &dev->ep[ep_addr];
 	return NULL;
 }
 
+static const char* std_req_name[] = {
+	"GET_STATUS",
+	"CLEAR_FEATURE",
+	"RESERVED",
+	"SET_FEATURE",
+	"RESERVED",
+	"SET_ADDRESS",
+	"GET_DESCRIPTOR",
+	"SET_DESCRIPTOR",
+	"GET_CONFIGURATION",
+	"SET_CONFIGURATION",
+	"GET_INTERFACE",
+	"SET_INTERFACE",
+	"SYNCH_FRAME"
+};
 
-static inline int
-port_paranoia_check(struct usb_serial_port *port, const char *function)
+static inline const char*
+get_std_req_name(int req)
 {
-	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;
+	return (req >= 0 && req <= 12) ? std_req_name[req] : "UNKNOWN";
 }
 
-static inline struct usb_serial*
-get_usb_serial (struct usb_serial_port *port, const char *function)
+#if 0
+static void
+dump_setup(devrequest* s)
 {
-	/* 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;
+	dbg(__FUNCTION__ ": requesttype=%d", s->requesttype);
+	dbg(__FUNCTION__ ": request=%d %s", s->request,
+	    get_std_req_name(s->request));
+	dbg(__FUNCTION__ ": value=0x%04x", s->wValue);
+	dbg(__FUNCTION__ ": index=%d", s->index);
+	dbg(__FUNCTION__ ": length=%d", s->length);
 }
+#endif
 
-
-static inline pkt_t *
-alloc_packet(int data_size)
+static inline usbdev_pkt_t *
+alloc_packet(endpoint_t * ep, int data_size, void* data)
 {
-	pkt_t* pkt = (pkt_t *)kmalloc(sizeof(pkt_t) + data_size, ALLOC_FLAGS);
+	usbdev_pkt_t* pkt =
+		(usbdev_pkt_t *)kmalloc(sizeof(usbdev_pkt_t) + data_size,
+					ALLOC_FLAGS);
 	if (!pkt)
 		return NULL;
+	pkt->ep_addr = ep->address;
 	pkt->size = data_size;
-	pkt->bufptr = pkt->buf;
-#ifndef USBDEV_PIO
-	pkt->bufptr = KSEG1ADDR(pkt->bufptr);
-#endif
+	pkt->status = 0;
 	pkt->next = NULL;
+	if (data)
+		memcpy(pkt->payload, data, data_size);
+
 	return pkt;
 }
 
 
 /*
  * Link a packet to the tail of the enpoint's packet list.
+ * EP spinlock must be held when calling.
  */
 static void
-link_packet(endpoint_t * ep, pkt_list_t * list, pkt_t * pkt)
+link_tail(endpoint_t * ep, pkt_list_t * list, usbdev_pkt_t * pkt)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ep->lock, flags);
-
 	if (!list->tail) {
 		list->head = list->tail = pkt;
 		list->count = 1;
@@ -471,24 +244,20 @@
 		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.
+ * Unlink and return a packet from the head of the given packet
+ * list. It is the responsibility of the caller to free the packet.
+ * EP spinlock must be held when calling.
  */
-static pkt_t *
-unlink_packet(endpoint_t * ep, pkt_list_t * list)
+static usbdev_pkt_t *
+unlink_head(pkt_list_t * list)
 {
-	unsigned long flags;
-	pkt_t *pkt;
-
-	spin_lock_irqsave(&ep->lock, flags);
+	usbdev_pkt_t *pkt;
 
 	pkt = list->head;
 	if (!pkt || !list->count) {
-		spin_unlock_irqrestore(&ep->lock, flags);
 		return NULL;
 	}
 
@@ -499,118 +268,107 @@
 	} 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.
+ * packet list. EP spinlock must be held when calling.
  */
-static pkt_t *
+static usbdev_pkt_t *
 add_packet(endpoint_t * ep, pkt_list_t * list, int size)
 {
-	pkt_t *pkt = alloc_packet(size);
+	usbdev_pkt_t *pkt = alloc_packet(ep, size, NULL);
 	if (!pkt)
 		return NULL;
 
-	link_packet(ep, list, pkt);
+	link_tail(ep, list, pkt);
 	return pkt;
 }
 
 
 /*
  * Unlink and free a packet from the head of the enpoint's
- * packet list.
+ * packet list. EP spinlock must be held when calling.
  */
 static inline void
-free_packet(endpoint_t * ep, pkt_list_t * list)
+free_packet(pkt_list_t * list)
 {
-	kfree(unlink_packet(ep, list));
+	kfree(unlink_head(list));
 }
 
+/* EP spinlock must be held when calling. */
 static inline void
-flush_pkt_list(endpoint_t * ep, pkt_list_t * list)
+flush_pkt_list(pkt_list_t * list)
 {
 	while (list->count)
-		free_packet(ep, list);
+		free_packet(list);
 }
 
-
+/* EP spinlock must be held when calling */
 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,
+		au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
+			  USBDEV_FSTAT_OF,
 			  ep->reg->write_fifo_status);
+		//udelay(100);
+		//au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		//	  ep->reg->write_fifo_status);
 	}
 }
 
-
+/* EP spinlock must be held when calling */
 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,
+		au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
+			  USBDEV_FSTAT_OF,
 			  ep->reg->read_fifo_status);
+		//udelay(100);
+		//au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
+		//	  ep->reg->read_fifo_status);
 	}
 }
 
 
+/* EP spinlock must be held when calling. */
 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);
+	flush_pkt_list(&ep->inlist);
+	flush_pkt_list(&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);
 }
 
-
+/* EP spinlock must be held when calling. */
 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);
+	warn(__FUNCTION__);
 
-	spin_unlock_irqrestore(&ep->lock, flags);
+	cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
+	au_writel(cs, ep->reg->ctrl_stat);
 }
 
+/* EP spinlock must be held when calling. */
 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);
+	warn(__FUNCTION__);
 
-	spin_unlock_irqrestore(&ep->lock, flags);
+	cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
+	au_writel(cs, ep->reg->ctrl_stat);
 }
 
 static void
@@ -620,147 +378,182 @@
 }
 
 
-#ifdef USBDEV_PIO
+/* EP spinlock must be held when calling. */
 static int
 endpoint_fifo_read(endpoint_t * ep)
 {
-	unsigned long flags;
 	int read_count = 0;
 	u8 *bufptr;
-	pkt_t *pkt = ep->outlist.tail;
+	usbdev_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;
+	bufptr = &pkt->payload[pkt->size];
+	while (au_readl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) {
+		*bufptr++ = au_readl(ep->reg->read_fifo) & 0xff;
 		read_count++;
 		pkt->size++;
 	}
-	pkt->bufptr = bufptr;
 
-	spin_unlock_irqrestore(&ep->lock, flags);
 	return read_count;
 }
 
-
+#if 0
+/* EP spinlock must be held when calling. */
 static int
-endpoint_fifo_write(endpoint_t * ep)
+endpoint_fifo_write(endpoint_t * ep, int index)
 {
-	unsigned long flags;
 	int write_count = 0;
 	u8 *bufptr;
-	pkt_t *pkt = ep->inlist.head;
+	usbdev_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);
+	bufptr = &pkt->payload[index];
+	while ((au_readl(ep->reg->write_fifo_status) &
+		USBDEV_FSTAT_FCNT_MASK) < EP_FIFO_DEPTH) {
+		if (bufptr < pkt->payload + pkt->size) {
+			au_writel(*bufptr++, ep->reg->write_fifo);
 			write_count++;
 		} else {
 			break;
 		}
 	}
-	pkt->bufptr = bufptr;
 
-	spin_unlock_irqrestore(&ep->lock, flags);
 	return write_count;
 }
-#endif				// USBDEV_PIO
+#endif
 
 /*
  * 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.
+ * EP spinlock must be held when calling.
  */
 static void
 kickstart_send_packet(endpoint_t * ep)
 {
 	u32 cs;
-	pkt_t *pkt = ep->inlist.head;
+	usbdev_pkt_t *pkt = ep->inlist.head;
 
-	dbg(__FUNCTION__ ": pkt=%p", pkt);
+	vdbg(__FUNCTION__ ": ep%d, pkt=%p", ep->address, pkt);
 
-	if (!pkt)
+	if (!pkt) {
+		err(__FUNCTION__ ": head=NULL! list->count=%d",
+		    ep->inlist.count);
 		return;
+	}
+
+	dma_cache_wback_inv((unsigned long)pkt->payload, pkt->size);
 
 	/*
-	 * The write fifo should already be drained if things are
-	 * working right, but flush it anyway just in case.
+	 * make sure FIFO is empty
 	 */
 	flush_write_fifo(ep);
-	cs = inl(ep->reg->ctrl_stat) & USBDEV_CS_STALL;
+
+	cs = au_readl(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)) {
+	au_writel(cs, ep->reg->ctrl_stat);
+
+	if (get_dma_active_buffer(ep->indma) == 1) {
 		set_dma_count1(ep->indma, pkt->size);
-		set_dma_addr1(ep->indma, virt_to_phys(pkt->bufptr));
+		set_dma_addr1(ep->indma, virt_to_phys(pkt->payload));
 		enable_dma_buffer1(ep->indma);	// reenable
 	} else {
 		set_dma_count0(ep->indma, pkt->size);
-		set_dma_addr0(ep->indma, virt_to_phys(pkt->bufptr));
+		set_dma_addr0(ep->indma, virt_to_phys(pkt->payload));
 		enable_dma_buffer0(ep->indma);	// reenable
 	}
-	enable_dma(ep->indma);
-#endif
+	if (dma_halted(ep->indma))
+		start_dma(ep->indma);
 }
 
 
 /*
  * This routine is called when a packet in the inlist has been
  * completed. Frees the completed packet and starts sending the
- * next.
+ * next. EP spinlock must be held when calling.
  */
-static void
+static usbdev_pkt_t *
 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);
+	usbdev_pkt_t *pkt = unlink_head(&ep->inlist);
+
+	if (pkt) {
+		pkt->status =
+			(au_readl(ep->reg->ctrl_stat) & USBDEV_CS_NAK) ?
+			PKT_STATUS_NAK : PKT_STATUS_ACK;
+
+		vdbg(__FUNCTION__ ": ep%d, %s pkt=%p, list count=%d",
+		     ep->address, (pkt->status & PKT_STATUS_NAK) ?
+		     "NAK" : "ACK", pkt, ep->inlist.count);
+	}
+
+	/*
+	 * The write fifo should already be drained if things are
+	 * working right, but flush it anyway just in case.
+	 */
+	flush_write_fifo(ep);
+
 	// begin transmitting next packet in the inlist
-	if (ep->inlist.count)
+	if (ep->inlist.count) {
 		kickstart_send_packet(ep);
-}
+	}
 
+	return pkt;
+}
 
 /*
- * 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. 
+ * 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. EP spinlock must be held when calling.
  */
-static pkt_t *
-receive_packet(endpoint_t * ep)
+static int
+send_packet(struct usb_dev* dev, usbdev_pkt_t *pkt, int async)
 {
-	pkt_t *pkt = unlink_packet(ep, &ep->outlist);
-	//dma_cache_inv((unsigned long)pkt->buf, pkt->size);
-	return pkt;
+	pkt_list_t *list;
+	endpoint_t* ep;
+
+	if (!pkt || !(ep = epaddr_to_ep(dev, pkt->ep_addr)))
+		return -EINVAL;
+
+	if (!pkt->size)
+		return 0;
+
+	list = &ep->inlist;
+
+	if (!async && list->count) {
+		halt_dma(ep->indma);
+		flush_pkt_list(list);
+	}
+
+	link_tail(ep, list, pkt);
+
+	vdbg(__FUNCTION__ ": ep%d, pkt=%p, size=%d, list count=%d",
+	     ep->address, pkt, 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);
+	}
+
+	return pkt->size;
 }
 
 /*
  * This routine is called to restart reception of a packet.
+ * EP spinlock must be held when calling.
  */
 static void
 kickstart_receive_packet(endpoint_t * ep)
 {
-	pkt_t *pkt;
+	usbdev_pkt_t *pkt;
 
 	// get and link a new packet for next reception
 	if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) {
@@ -768,23 +561,21 @@
 		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)) {
+	if (get_dma_active_buffer(ep->outdma) == 1) {
+		clear_dma_done1(ep->outdma);
 		set_dma_count1(ep->outdma, ep->max_pkt_size);
-		set_dma_addr1(ep->outdma, virt_to_phys(pkt->bufptr));
+		set_dma_count0(ep->outdma, 0);
+		set_dma_addr1(ep->outdma, virt_to_phys(pkt->payload));
 		enable_dma_buffer1(ep->outdma);	// reenable
 	} else {
+		clear_dma_done0(ep->outdma);
 		set_dma_count0(ep->outdma, ep->max_pkt_size);
-		set_dma_addr0(ep->outdma, virt_to_phys(pkt->bufptr));
+		set_dma_count1(ep->outdma, 0);
+		set_dma_addr0(ep->outdma, virt_to_phys(pkt->payload));
 		enable_dma_buffer0(ep->outdma);	// reenable
 	}
-	enable_dma(ep->outdma);
-#endif
+	if (dma_halted(ep->outdma))
+		start_dma(ep->outdma);
 }
 
 
@@ -795,404 +586,499 @@
  * 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.
+ * EP spinlock must be held when calling.
  */
-static void
+static usbdev_pkt_t *
 receive_packet_complete(endpoint_t * ep)
 {
-	pkt_t *pkt = ep->outlist.tail;
+	usbdev_pkt_t *pkt = ep->outlist.tail;
+	u32 cs;
+
+	halt_dma(ep->outdma);
+
+	cs = au_readl(ep->reg->ctrl_stat);
 
 	if (!pkt)
-		return;
+		return NULL;
 
-	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);
+	if (pkt->size)
+		dma_cache_inv((unsigned long)pkt->payload, pkt->size);
+	/*
+	 * need to pull out any remaining bytes in the FIFO.
+	 */
+	endpoint_fifo_read(ep);
+	/*
+	 * should be drained now, but flush anyway just in case.
+	 */
+	flush_read_fifo(ep);
+
+	pkt->status = (cs & USBDEV_CS_NAK) ? PKT_STATUS_NAK : PKT_STATUS_ACK;
+	if (ep->address == 0 && (cs & USBDEV_CS_SU))
+		pkt->status |= PKT_STATUS_SU;
+
+	vdbg(__FUNCTION__ ": ep%d, %s pkt=%p, size=%d",
+	     ep->address, (pkt->status & PKT_STATUS_NAK) ?
+	     "NAK" : "ACK", pkt, pkt->size);
 
 	kickstart_receive_packet(ep);
-}
 
+	return pkt;
+}
 
 
 /*
- * 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.
+ ****************************************************************************
+ * Here starts the standard device request handlers. They are
+ * all called by do_setup() via a table of function pointers.
+ ****************************************************************************
  */
-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;
+static ep0_stage_t
+do_get_status(struct usb_dev* dev, devrequest* setup)
+{
+	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(&dev->ep[0]); // Stall End Point 0
+		break;
 	}
 
-	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);
+	return STATUS_STAGE;
+}
 
-	link_packet(ep, list, pkt);
+static ep0_stage_t
+do_clear_feature(struct usb_dev* dev, devrequest* setup)
+{
+	switch (setup->requesttype) {
+	case 0x00:	// Device
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
+			dev->remote_wakeup_en = 0;
+	else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	case 0x02:	// End Point
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
+			endpoint_t *ep =
+				epaddr_to_ep(dev,
+					     le16_to_cpu(setup->index) & 0xff);
+
+			endpoint_unstall(ep);
+			endpoint_reset_datatoggle(ep);
+		} else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	}
 
-	spin_lock_irqsave(&ep->lock, flags);
+	return SETUP_STAGE;
+}
 
-	dbg(__FUNCTION__ ": size=%d, list count=%d", pkt->size, list->count);
+static ep0_stage_t
+do_reserved(struct usb_dev* dev, devrequest* setup)
+{
+	// Invalid request, stall End Point 0
+	endpoint_stall(&dev->ep[0]);
+	return SETUP_STAGE;
+}
 
-	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);
+static ep0_stage_t
+do_set_feature(struct usb_dev* dev, devrequest* setup)
+{
+	switch (setup->requesttype) {
+	case 0x00:	// Device
+		if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
+			dev->remote_wakeup_en = 1;
+		else
+			endpoint_stall(&dev->ep[0]);
+		break;
+	case 0x02:	// End Point
+		if ((le16_to_cpu(setup->vwValue) & 0xff) == 0) {
+			endpoint_t *ep =
+				epaddr_to_ep(dev,
+					     le16_to_cpu(setup->index) & 0xff);
+
+			endpoint_stall(ep);
+		} else
+			endpoint_stall(&dev->ep[0]);
+		break;
 	}
 
-	spin_unlock_irqrestore(&ep->lock, flags);
-	return data_len;
+	return SETUP_STAGE;
 }
 
-
-// SETUP packet request parser
-static void
-process_setup (struct usb_serial* serial, struct usb_ctrlrequest* setup)
+static ep0_stage_t
+do_set_address(struct usb_dev* dev, devrequest* setup)
 {
-	int desc_len, strnum;
+	int new_state = dev->state;
+	int new_addr = le16_to_cpu(setup->wValue);
 
-	dbg(__FUNCTION__ ": req %d", setup->request);
+	dbg(__FUNCTION__ ": our address=%d", new_addr);
 
-	switch (setup->request) {
-	case USB_REQ_SET_ADDRESS:
-		serial->address = le16_to_cpu(setup->wValue);
-		dbg(__FUNCTION__ ": our address=%d", serial->address);
-		if (serial->address > 127 || serial->state == CONFIGURED) {
+	if (new_addr > 127) {
 			// 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->wLength);
+		new_state = DEFAULT;
+		dev->address = 0;
+	} else if (dev->address != new_addr) {
+		dev->address = new_addr;
+		new_state = ADDRESS;
+	}
+
+	if (dev->state != new_state) {
+		dev->state = new_state;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_get_descriptor(struct usb_dev* dev, devrequest* setup)
+{
+	int strnum, desc_len = le16_to_cpu(setup->length);
+
 		switch (le16_to_cpu(setup->wValue) >> 8) {
 		case USB_DT_DEVICE:
 			// send device descriptor!
-			desc_len = desc_len > serial->dev_desc->bLength ?
-			    serial->dev_desc->bLength : desc_len;
+		desc_len = desc_len > dev->dev_desc->bLength ?
+			dev->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);
+		send_packet(dev, alloc_packet(&dev->ep[0], desc_len,
+					      dev->dev_desc), 0);
 			break;
 		case USB_DT_CONFIG:
 			// If the config descr index in low-byte of
-			// setup->value	is valid, send config descr,
+			// setup->wValue	is valid, send config descr,
 			// otherwise stall ep0.
 			if ((le16_to_cpu(setup->wValue) & 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);
+				send_packet(dev,
+					    alloc_packet(&dev->ep[0],
+							 desc_len,
+							 dev->conf_desc),
+					    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);
+				int len = dev->conf_desc->wTotalLength;
+				dbg("sending whole config desc,"
+				    " size=%d, our size=%d", desc_len, len);
+				desc_len = desc_len > len ? len : desc_len;
+				send_packet(dev,
+					    alloc_packet(&dev->ep[0],
+							 desc_len,
+							 dev->full_conf_desc),
+					    0);
 				}
 			} else
-				endpoint_stall(&serial->ep_ctrl);
+			endpoint_stall(&dev->ep[0]);
 			break;
 		case USB_DT_STRING:
-			// If the string descr index in low-byte of setup->value
+			// If the string descr index in low-byte of setup->wValue
 			// is valid, send string descr, otherwise stall ep0.
 			strnum = le16_to_cpu(setup->wValue) & 0xff;
 			if (strnum >= 0 && strnum < 6) {
 				struct usb_string_descriptor *desc =
-				    serial->str_desc[strnum];
+				dev->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);
+			send_packet(dev,
+				    alloc_packet(&dev->ep[0], desc_len,
+						 desc), 0);
 			} else
-				endpoint_stall(&serial->ep_ctrl);
+			endpoint_stall(&dev->ep[0]);
 			break;
-		default:	// Invalid request
-			dbg("invalid get desc=%d, stalled",
+	default:
+		// Invalid request
+		err("invalid get desc=%d, stalled",
 			    le16_to_cpu(setup->wValue) >> 8);
-			endpoint_stall(&serial->ep_ctrl);	// Stall endpoint 0
+		endpoint_stall(&dev->ep[0]);	// Stall endpoint 0
 			break;
 		}
-		break;
-	case USB_REQ_SET_DESCRIPTOR:
-		// FIXME: anything to set here?
-		break;
-	case USB_REQ_GET_INTERFACE:
+
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_set_descriptor(struct usb_dev* dev, devrequest* setup)
+{
+	// TODO: implement
+	// there will be an OUT data stage (the descriptor to set)
+	return DATA_STAGE;
+}
+
+static ep0_stage_t
+do_get_configuration(struct usb_dev* dev, devrequest* setup)
+{
+	// send dev->configuration
+	dbg("sending config");
+	send_packet(dev, alloc_packet(&dev->ep[0], 1, &dev->configuration),
+		    0);
+	return STATUS_STAGE;
+}
+
+static ep0_stage_t
+do_set_configuration(struct usb_dev* dev, devrequest* setup)
+{
+	// set active config to low-byte of setup->wValue
+	dev->configuration = le16_to_cpu(setup->wValue) & 0xff;
+	dbg("set config, config=%d", dev->configuration);
+	if (!dev->configuration && dev->state > DEFAULT) {
+		dev->state = ADDRESS;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	} else if (dev->configuration == 1) {
+		dev->state = CONFIGURED;
+		/* inform function layer of usbdev state change */
+		dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
+	} else {
+		// FIXME: "respond with request error" - how?
+	}
+
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_get_interface(struct usb_dev* dev, devrequest* setup)
+{
 		// interface must be zero.
-		if ((le16_to_cpu(setup->wIndex) & 0xff) ||
-		    serial->state == ADDRESS) {
+	if ((le16_to_cpu(setup->index) & 0xff) || dev->state == ADDRESS) {
 			// FIXME: respond with "request error". how?
-		} else if (serial->state == CONFIGURED) {
-			// send serial->alternate_setting
+	} else if (dev->state == CONFIGURED) {
+		// send dev->alternate_setting
 			dbg("sending alt setting");
-			send_packet(&serial->ep_ctrl,
-				    &serial->alternate_setting, 1, 0);
+		send_packet(dev, alloc_packet(&dev->ep[0], 1,
+					      &dev->alternate_setting), 0);
 		}
-		break;
-	case USB_REQ_SET_INTERFACE:
-		if (serial->state == ADDRESS) {
+
+	return STATUS_STAGE;
+
+}
+
+static ep0_stage_t
+do_set_interface(struct usb_dev* dev, devrequest* setup)
+{
+	if (dev->state == ADDRESS) {
 			// FIXME: respond with "request error". how?
-		} else if (serial->state == CONFIGURED) {
-			serial->interface = le16_to_cpu(setup->wIndex) & 0xff;
-			serial->alternate_setting =
+	} else if (dev->state == CONFIGURED) {
+		dev->interface = le16_to_cpu(setup->index) & 0xff;
+		dev->alternate_setting =
 			    le16_to_cpu(setup->wValue) & 0xff;
 			// interface and alternate_setting must be zero
-			if (serial->interface || serial->alternate_setting) {
+		if (dev->interface || dev->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->wValue) & 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->bRequestType) {
-		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->wValue) & 0xff) == 1)
-				serial->remote_wakeup_en = 0;
-			else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
-				endpoint_t *ep =
-				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->wIndex) & 0xff);
 
-				endpoint_unstall(ep);
-				endpoint_reset_datatoggle(ep);
-			} else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
+	return SETUP_STAGE;
+}
+
+static ep0_stage_t
+do_synch_frame(struct usb_dev* dev, devrequest* setup)
+{
+	// TODO
+	return SETUP_STAGE;
+}
+
+typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev,
+				    devrequest* setup);
+
+
+/* Table of the standard device request handlers */
+static const req_method_t req_method[] = {
+	do_get_status,
+	do_clear_feature,
+	do_reserved,
+	do_set_feature,
+	do_reserved,
+	do_set_address,
+	do_get_descriptor,
+	do_set_descriptor,
+	do_get_configuration,
+	do_set_configuration,
+	do_get_interface,
+	do_set_interface,
+	do_synch_frame
+};
+
+
+// SETUP packet request dispatcher
+static void
+do_setup (struct usb_dev* dev, devrequest* setup)
+{
+	req_method_t m;
+
+	dbg(__FUNCTION__ ": req %d %s", setup->request,
+	    get_std_req_name(setup->request));
+
+	if ((setup->requesttype & USB_TYPE_MASK) != USB_TYPE_STANDARD ||
+	    (setup->requesttype & USB_RECIP_MASK) != USB_RECIP_DEVICE) {
+		err(__FUNCTION__ ": invalid requesttype 0x%02x",
+		    setup->requesttype);
+		return;
 		}
-		break;
-	case USB_REQ_SET_FEATURE:
-		switch (setup->bRequestType) {
-		case 0x00:	// Device
-			if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
-				serial->remote_wakeup_en = 1;
+
+	if ((setup->requesttype & 0x80) == USB_DIR_OUT && setup->length)
+		dbg(__FUNCTION__ ": OUT phase! length=%d", setup->length);
+
+	if (setup->request < sizeof(req_method)/sizeof(req_method_t))
+		m = req_method[setup->request];
 			else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
-				endpoint_t *ep =
-				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->wIndex) & 0xff);
+		m = do_reserved;
 
-				endpoint_stall(ep);
-			} else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		}
-		break;
-	default:
-		endpoint_stall(&serial->ep_ctrl);	// Stall End Point 0
-		break;
-	}
+	dev->ep0_stage = (*m)(dev, setup);
 }
 
-
 /*
- * A complete packet (SETUP, DATA0, or DATA1) has been received
- * on the given endpoint's fifo.
+ * A SETUP, DATA0, or DATA1 packet has been received
+ * on the default control endpoint's fifo.
  */
 static void
-process_complete (struct usb_serial* serial, int fifo_num)
+process_ep0_receive (struct usb_dev* dev)
 {
-	endpoint_t *ep = fifonum_to_ep(serial, fifo_num);
-	struct usb_serial_port *port = NULL;
-	pkt_t *pkt = 0;
-	u32 cs;
+	endpoint_t *ep0 = &dev->ep[0];
+	usbdev_pkt_t *pkt;
 
-	cs = inl(ep->reg->ctrl_stat);
+	spin_lock(&ep0->lock);
 
-	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);
+	pkt = receive_packet_complete(ep0);
+	if (!pkt) {
+		// FIXME: should  put a warn/err here.
+		spin_unlock(&ep0->lock);
 			return;
 		}
-	
-		// SETUP packet received ?
-		//if (cs & USBDEV_CS_SU) { FIXME: uncomment!
-			if (pkt->size == sizeof(struct usb_ctrlrequest)) {
-				struct usb_ctrlrequest setup;
-			if ((cs & (USBDEV_CS_NAK | USBDEV_CS_ACK)) ==
-			    USBDEV_CS_ACK)
-					dbg("got SETUP");
+
+	// unlink immediately from endpoint.
+	unlink_head(&ep0->outlist);
+
+	// override current stage if h/w says it's a setup packet
+	if (pkt->status & PKT_STATUS_SU)
+		dev->ep0_stage = SETUP_STAGE;
+
+	switch (dev->ep0_stage) {
+	case SETUP_STAGE:
+		vdbg("SU bit is %s in setup stage",
+		     (pkt->status & PKT_STATUS_SU) ? "set" : "not set");
+
+			if (pkt->size == sizeof(devrequest)) {
+#ifdef VDEBUG
+			if (pkt->status & PKT_STATUS_ACK)
+				vdbg("received SETUP");
 				else
-					dbg("got NAK SETUP, cs=%08x", cs);
-			memcpy(&setup, pkt->bufptr, sizeof(struct usb_ctrlrequest));
-				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);
+				vdbg("received NAK SETUP");
+#endif
+			do_setup(dev, (devrequest*)pkt->payload);
+		} else
+			err(__FUNCTION__ ": wrong size SETUP received");
+		break;
+	case DATA_STAGE:
+		/*
+		 * this setup has an OUT data stage. Of the standard
+		 * device requests, only set_descriptor has this stage,
+		 * so this packet is that descriptor. TODO: drop it for
+		 * now, set_descriptor not implemented.
+		 *
+		 * Need to place a byte in the write FIFO here, to prepare
+		 * to send a zero-length DATA ack packet to the host in the
+		 * STATUS stage.
+		 */
+		au_writel(0, ep0->reg->write_fifo);
+		dbg("received OUT stage DATAx on EP0, size=%d", pkt->size);
+		dev->ep0_stage = SETUP_STAGE;
+		break;
+	case STATUS_STAGE:
+		// this setup had an IN data stage, and host is ACK'ing
+		// the packet we sent during that stage.
+		if (pkt->size != 0)
+			warn("received non-zero ACK on EP0??");
+#ifdef VDEBUG
+		else
+			vdbg("received ACK on EP0");
+#endif
+		dev->ep0_stage = SETUP_STAGE;
+		break;
 		}
 
-		spin_unlock(&ep->lock);
+	spin_unlock(&ep0->lock);
 		// we're done processing the packet, free it
 		kfree(pkt);
-		break;
+}
+
+
+/*
+ * A DATA0/1 packet has been received on one of the OUT endpoints (4 or 5)
+ */
+static void
+process_ep_receive (struct usb_dev* dev, endpoint_t *ep)
+{
+	usbdev_pkt_t *pkt;
 
-	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);
+	pkt = 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;
-	}
+	dev->func_cb(CB_PKT_COMPLETE, (unsigned long)pkt, dev->cb_data);
 }
 
 
 
-// This ISR needs to ack both the complete and suspend events
+/* This ISR handles the receive 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;
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
 	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
+	status = au_readl(USBD_INTSTAT);
+	au_writel(status, USBD_INTSTAT);	// ack'em
 
-	for (i = 0; i < 6; i++) {
-		if (status & (1 << i))
-			process_complete(serial, i);
-	}
+	if (status & (1<<0))
+		process_ep0_receive(dev);
+	if (status & (1<<4))
+		process_ep_receive(dev, &dev->ep[4]);
+	if (status & (1<<5))
+		process_ep_receive(dev, &dev->ep[5]);
 }
 
 
+/* This ISR handles the DMA done events on EP0 */
 static void
-dma_done_ctrl(struct usb_serial* serial)
+dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	endpoint_t *ep = &serial->ep_ctrl;
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	usbdev_pkt_t* pkt;
+	endpoint_t *ep0 = &dev->ep[0];
 	u32 cs0, buff_done;
 
-	spin_lock(&ep->lock);
-	cs0 = inl(ep->reg->ctrl_stat);
+	spin_lock(&ep0->lock);
+	cs0 = au_readl(ep0->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
+	if ((buff_done = get_dma_buffer_done(ep0->indma)) != 0) {
+		// transmitted a DATAx packet during DATA stage
+		// 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);
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep0->indma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep0->indma);
+
+		pkt = send_packet_complete(ep0);
+		if (pkt)
+			kfree(pkt);
 	}
 
 	/*
@@ -1200,645 +1086,477 @@
 	 * the receive packet complete intr should happen
 	 * before the DMA done intr occurs.
 	 */
-	if ((buff_done = get_dma_buffer_done(ep->outdma)) != 0) {
+	if ((buff_done = get_dma_buffer_done(ep0->outdma)) != 0) {
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
-			clear_dma_done0(ep->outdma);
-		else
-			clear_dma_done1(ep->outdma);
+		if (buff_done & DMA_D0)
+			clear_dma_done0(ep0->outdma);
+		if (buff_done & DMA_D1)
+			clear_dma_done1(ep0->outdma);
+
+		//process_ep0_receive(dev);
 	}
 
-	spin_unlock(&ep->lock);
+	spin_unlock(&ep0->lock);
 }
 
+/* This ISR handles the DMA done events on endpoints 2,3,4,5 */
 static void
-dma_done_port(struct usb_serial_port * port)
+dma_done_ep_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	endpoint_t *ep;
+	struct usb_dev *dev = (struct usb_dev *) dev_id;
+	int i;
+
+	for (i = 2; i < 6; i++) {
 	u32 buff_done;
+		usbdev_pkt_t* pkt;
+		endpoint_t *ep = &dev->ep[i];
+
+		if (!ep->active) continue;
 
-	// 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
+
+		if (ep->direction == USB_DIR_IN) {
+			buff_done = get_dma_buffer_done(ep->indma);
+			if (buff_done != 0) {
+				// transmitted a DATAx pkt on the IN ep
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
+		if (buff_done & DMA_D0)
 			clear_dma_done0(ep->indma);
-		else
+		if (buff_done & DMA_D1)
 			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);
+				pkt = send_packet_complete(ep);
 
+				spin_unlock(&ep->lock);
+				dev->func_cb(CB_PKT_COMPLETE,
+					     (unsigned long)pkt,
+					     dev->cb_data);
+				spin_lock(&ep->lock);
+			}
+		} else {
 	/*
-	 * Now check packet receive done (bulk OUT ep). Shouldn't
-	 * get these, the receive packet complete intr should happen
+			 * Check packet receive done (OUT ep). Shouldn't get
+			 * these, the rx 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
+			buff_done = get_dma_buffer_done(ep->outdma);
+			if (buff_done != 0) {
+				// received a DATAx pkt on the OUT ep
 		// clear DMA done bit
-		if (buff_done == DMA_D0)
+		if (buff_done & DMA_D0)
 			clear_dma_done0(ep->outdma);
-		else
+		if (buff_done & DMA_D1)
 			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;
 
+				//process_ep_receive(dev, ep);
 	}
-
-	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(&ep->lock);
 	}
-
-	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)
+/***************************************************************************
+ * Here begins the external interface functions
+ ***************************************************************************
+ */
+
+/*
+ * allocate a new packet
+ */
+int
+usbdev_alloc_packet(int ep_addr, int data_size, usbdev_pkt_t** pkt)
 {
-	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;
+	endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
+	usbdev_pkt_t* lpkt = NULL;
 
-	if (!serial)
+	if (!ep || !ep->active || ep->address < 2)
 		return -ENODEV;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not opened");
+	if (data_size > ep->max_pkt_size)
 		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);
+	lpkt = *pkt = alloc_packet(ep, data_size, NULL);
+	if (!lpkt)
+		return -ENOMEM;
+	return 0;
 }
 
 
-static int serial_write_room(struct tty_struct *tty)
+/*
+ * packet send
+ */
+int
+usbdev_send_packet(int ep_addr, usbdev_pkt_t * pkt)
 {
-	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;
+	unsigned long flags;
+	int count;
+	endpoint_t * ep;
 
-	if (!serial)
+	if (!pkt || !(ep = epaddr_to_ep(&usbdev, pkt->ep_addr)) ||
+	    !ep->active || ep->address < 2)
 		return -ENODEV;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
+	if (ep->direction != USB_DIR_IN)
 		return -EINVAL;
-	}
 
-	return ep->max_pkt_size;
-}
+	spin_lock_irqsave(&ep->lock, flags);
+	count = send_packet(&usbdev, pkt, 1);
+	spin_unlock_irqrestore(&ep->lock, flags);
 
+	return count;
+}
 
-static int serial_chars_in_buffer(struct tty_struct *tty)
+/*
+ * packet receive
+ */
+int
+usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt)
 {
-	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;
+	usbdev_pkt_t* lpkt = NULL;
+	endpoint_t *ep = epaddr_to_ep(&usbdev, ep_addr);
 
-	if (!serial)
+	if (!ep || !ep->active || ep->address < 2)
 		return -ENODEV;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
+	if (ep->direction != USB_DIR_OUT)
 		return -EINVAL;
-	}
 
 	spin_lock_irqsave(&ep->lock, flags);
-	for (scan = list->head; scan; scan = scan->next)
-		chars += scan->size;
+	if (ep->outlist.count > 1)
+		lpkt = unlink_head(&ep->outlist);
 	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;
+	if (!lpkt) {
+		/* no packet available */
+		*pkt = NULL;
+		return -ENODATA;
 	}
-	// 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__);
+	*pkt = lpkt;
 
-	if (!serial)
-		return;
-
-	if (!port->active) {
-		dbg(__FUNCTION__ " - port not open");
-		return;
-	}
-	// FIXME: anything to do?
+	return lpkt->size;
 }
 
 
-static int serial_ioctl(struct tty_struct *tty, struct file *file,
-			unsigned int cmd, unsigned long arg)
+/*
+ * return total queued byte count on the endpoint.
+ */
+int
+usbdev_get_byte_count(int ep_addr)
 {
-	struct usb_serial_port *port =
-	    (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial(port, __FUNCTION__);
+        unsigned long flags;
+        pkt_list_t *list;
+        usbdev_pkt_t *scan;
+        int count = 0;
+	endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
 
-	if (!serial)
+	if (!ep || !ep->active || ep->address < 2)
 		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?
-}
-
+	if (ep->direction == USB_DIR_IN) {
+		list = &ep->inlist;
 
-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;
-	}
+		spin_lock_irqsave(&ep->lock, flags);
+		for (scan = list->head; scan; scan = scan->next)
+			count += scan->size;
+		spin_unlock_irqrestore(&ep->lock, flags);
+	} else {
+		list = &ep->outlist;
 
-	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);
+		spin_lock_irqsave(&ep->lock, flags);
+		if (list->count > 1) {
+			for (scan = list->head; scan != list->tail;
+			     scan = scan->next)
+				count += scan->size;
 	}
-
-	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;
+		spin_unlock_irqrestore(&ep->lock, flags);
 	}
 
-	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);
+	return count;
 }
 
 
-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)
+void
+usbdev_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
+	au_writel(0, USBD_INTEN);	// disable usb dev ints
+	au_writel(0, USBD_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_irq(AU1000_USB_DEV_REQ_INT, &usbdev);
+	free_irq(AU1000_USB_DEV_SUS_INT, &usbdev);
+
+	// free all control endpoint resources
+	ep = &usbdev.ep[0];
 	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 ep resources
+	for (i = 2; i < 6; i++) {
+		ep = &usbdev.ep[i];
+		if (!ep->active) continue;
 
-		// free port's bulk OUT endpoint resources
-		ep = &usbserial.port[i].ep_bulkout;
-		//free_irq(ep->outirq, &usbserial);
+		if (ep->direction == USB_DIR_IN) {
+			free_au1000_dma(ep->indma);
+		} else {
 		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);
+	if (usbdev.full_conf_desc)
+		kfree(usbdev.full_conf_desc);
 }
 
-int usbdev_serial_init(void)
-{
-	struct usb_serial_port *port;
+int
+usbdev_init(struct usb_device_descriptor* dev_desc,
+	    struct usb_config_descriptor* config_desc,
+	    struct usb_interface_descriptor* if_desc,
+	    struct usb_endpoint_descriptor* ep_desc,
+	    struct usb_string_descriptor* str_desc[],
+	    void (*cb)(usbdev_cb_type_t, unsigned long, void *),
+	    void* cb_data)
+{
+	endpoint_t *ep0;
+	int i, ret=0;
+	u8* fcd;
+
+	if (dev_desc->bNumConfigurations > 1 ||
+	    config_desc->bNumInterfaces > 1 ||
+	    if_desc->bNumEndpoints > 4) {
+		err("Only one config, one i/f, and no more "
+		    "than 4 ep's allowed");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!cb) {
+		err("Function-layer callback required");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (dev_desc->bMaxPacketSize0 != USBDEV_EP0_MAX_PACKET_SIZE) {
+		warn("EP0 Max Packet size must be %d",
+		     USBDEV_EP0_MAX_PACKET_SIZE);
+		dev_desc->bMaxPacketSize0 = USBDEV_EP0_MAX_PACKET_SIZE;
+	}
+
+	memset(&usbdev, 0, sizeof(struct usb_dev));
+
+	usbdev.state = DEFAULT;
+	usbdev.dev_desc = dev_desc;
+	usbdev.if_desc = if_desc;
+	usbdev.conf_desc = config_desc;
+	for (i=0; i<6; i++)
+		usbdev.str_desc[i] = str_desc[i];
+	usbdev.func_cb = cb;
+	usbdev.cb_data = cb_data;
+
+	/* Initialize default control endpoint */
+	ep0 = &usbdev.ep[0];
+	ep0->active = 1;
+	ep0->type = CONTROL_EP;
+	ep0->max_pkt_size = USBDEV_EP0_MAX_PACKET_SIZE;
+	spin_lock_init(&ep0->lock);
+	ep0->desc = NULL;	// ep0 has no descriptor
+	ep0->address = 0;
+	ep0->direction = 0;
+	ep0->reg = &ep_reg[0];
+
+	/* Initialize the other requested endpoints */
+	for (i = 0; i < if_desc->bNumEndpoints; i++) {
+		struct usb_endpoint_descriptor* epd = &ep_desc[i];
 	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;
+		if ((epd->bEndpointAddress & 0x80) == USB_DIR_IN) {
+			ep = &usbdev.ep[2];
+			ep->address = 2;
+			if (ep->active) {
+				ep = &usbdev.ep[3];
+				ep->address = 3;
+				if (ep->active) {
+					err("too many IN ep's requested");
+					ret = -ENODEV;
+					goto out;
 	}
-
-	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;
+		} else {
+			ep = &usbdev.ep[4];
+			ep->address = 4;
+			if (ep->active) {
+				ep = &usbdev.ep[5];
+				ep->address = 5;
+				if (ep->active) {
+					err("too many OUT ep's requested");
+					ret = -ENODEV;
+					goto 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;
+
+		ep->active = 1;
+		epd->bEndpointAddress &= ~0x0f;
+		epd->bEndpointAddress |= (u8)ep->address;
+		ep->direction = epd->bEndpointAddress & 0x80;
+		ep->type = epd->bmAttributes & 0x03;
+		ep->max_pkt_size = epd->wMaxPacketSize;
 		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->desc = epd;
+		ep->reg = &ep_reg[ep->address];
 		}
-		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
+
+	/*
+	 * initialize the full config descriptor
+	 */
+	usbdev.full_conf_desc = fcd = kmalloc(config_desc->wTotalLength,
+					      ALLOC_FLAGS);
+	if (!fcd) {
+		err("failed to alloc full config descriptor");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(fcd, config_desc, USB_DT_CONFIG_SIZE);
+	fcd += USB_DT_CONFIG_SIZE;
+	memcpy(fcd, if_desc, USB_DT_INTERFACE_SIZE);
+	fcd += USB_DT_INTERFACE_SIZE;
+	for (i = 0; i < if_desc->bNumEndpoints; i++) {
+		memcpy(fcd, &ep_desc[i], USB_DT_ENDPOINT_SIZE);
+		fcd += USB_DT_ENDPOINT_SIZE;
 	}
 
-	// enable device controller
-	outl_sync(0x0002, USB_DEV_ENABLE);
+	/* Now we're ready to enable the controller */
+	au_writel(0x0002, USBD_ENABLE);
 	udelay(100);
-	outl_sync(0x0003, USB_DEV_ENABLE);
+	au_writel(0x0003, USBD_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);
+	/* build and send config table based on ep descriptors */
+	for (i = 0; i < 6; i++) {
+		endpoint_t *ep;
+		if (i == 1)
+			continue; // skip dummy ep
+		ep = &usbdev.ep[i];
+		if (ep->active) {
+			au_writel((ep->address << 4) | 0x04, USBD_CONFIG);
+			au_writel(((ep->max_pkt_size & 0x380) >> 7) |
+				  (ep->direction >> 4) | (ep->type << 4),
+				  USBD_CONFIG);
+			au_writel((ep->max_pkt_size & 0x7f) << 1, USBD_CONFIG);
+			au_writel(0x00, USBD_CONFIG);
+			au_writel(ep->address, USBD_CONFIG);
+		} else {
+			u8 dir = (i==2 || i==3) ? DIR_IN : DIR_OUT;
+			au_writel((i << 4) | 0x04, USBD_CONFIG);
+			au_writel(((16 & 0x380) >> 7) | dir |
+				  (BULK_EP << 4), USBD_CONFIG);
+			au_writel((16 & 0x7f) << 1, USBD_CONFIG);
+			au_writel(0x00, USBD_CONFIG);
+			au_writel(i, USBD_CONFIG);
+		}
 	}
 
 	/*
 	 * Enable Receive FIFO Complete interrupts only. Transmit
 	 * complete is being handled by the DMA done interrupts.
 	 */
-	outl_sync(0x31, USB_DEV_INT_ENABLE);
+	au_writel(0x31, USBD_INTEN);
 
-	return 0;
+	/*
+	 * Controller is now enabled, request DMA and IRQ
+	 * resources.
+	 */
 
-      err_out:
-	usbdev_serial_exit();
-	return -1;
-}
+	/* request the USB device transfer complete interrupt */
+	if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, SA_INTERRUPT,
+			"USBdev req", &usbdev)) {
+		err("Can't get device request intr");
+		ret = -ENXIO;
+		goto out;
+	}
+	/* request the USB device suspend interrupt */
+	if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, SA_INTERRUPT,
+			"USBdev sus", &usbdev)) {
+		err("Can't get device suspend intr");
+		ret = -ENXIO;
+		goto out;
+	}
+
+	/* Request EP0 DMA and IRQ */
+	if ((ep0->indma = request_au1000_dma(ep_dma_id[0].id,
+					     ep_dma_id[0].str,
+					     dma_done_ep0_intr,
+					     SA_INTERRUPT,
+					     &usbdev)) < 0) {
+		err("Can't get %s DMA", ep_dma_id[0].str);
+		ret = -ENXIO;
+		goto out;
+	}
+	if ((ep0->outdma = request_au1000_dma(ep_dma_id[1].id,
+					      ep_dma_id[1].str,
+					      NULL, 0, NULL)) < 0) {
+		err("Can't get %s DMA", ep_dma_id[1].str);
+		ret = -ENXIO;
+		goto out;
+	}
+
+	// Flush the ep0 buffers and FIFOs
+	endpoint_flush(ep0);
+	// start packet reception on ep0
+	kickstart_receive_packet(ep0);
+
+	/* Request DMA and IRQ for the other endpoints */
+	for (i = 2; i < 6; i++) {
+		endpoint_t *ep = &usbdev.ep[i];
+		if (!ep->active)
+			continue;
+
+		// Flush the endpoint buffers and FIFOs
+		endpoint_flush(ep);
 
+		if (ep->direction == USB_DIR_IN) {
+			ep->indma =
+				request_au1000_dma(ep_dma_id[ep->address].id,
+						   ep_dma_id[ep->address].str,
+						   dma_done_ep_intr,
+						   SA_INTERRUPT,
+						   &usbdev);
+			if (ep->indma < 0) {
+				err("Can't get %s DMA",
+				    ep_dma_id[ep->address].str);
+				ret = -ENXIO;
+				goto out;
+			}
+		} else {
+			ep->outdma =
+				request_au1000_dma(ep_dma_id[ep->address].id,
+						   ep_dma_id[ep->address].str,
+						   NULL, 0, NULL);
+			if (ep->outdma < 0) {
+				err("Can't get %s DMA",
+				    ep_dma_id[ep->address].str);
+				ret = -ENXIO;
+				goto out;
+			}
+
+			// start packet reception on OUT endpoint
+			kickstart_receive_packet(ep);
+		}
+	}
+
+ out:
+	if (ret)
+		usbdev_exit();
+	return ret;
+}
 
-module_init(usbdev_serial_init);
-module_exit(usbdev_serial_exit);
+EXPORT_SYMBOL(usbdev_init);
+EXPORT_SYMBOL(usbdev_exit);
+EXPORT_SYMBOL(usbdev_alloc_packet);
+EXPORT_SYMBOL(usbdev_receive_packet);
+EXPORT_SYMBOL(usbdev_send_packet);
+EXPORT_SYMBOL(usbdev_get_byte_count);
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1000/Makefile linux-2.4.20-pre7/arch/mips/au1000/pb1000/Makefile
--- linux-2.4.20-pre6/arch/mips/au1000/pb1000/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1000/Makefile	Thu Sep 12 20:01:39 2002
@@ -10,10 +10,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
 
 O_TARGET := pb1000.o
 
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1000/init.c linux-2.4.20-pre7/arch/mips/au1000/pb1000/init.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1000/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1000/init.c	Thu Sep 12 20:01:39 2002
@@ -34,7 +34,6 @@
 #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>
@@ -59,7 +58,7 @@
 	prom_envp = envp;
 
 	mips_machgroup = MACH_GROUP_ALCHEMY;
-	mips_machtype = MACH_PB1000;  
+	mips_machtype = MACH_PB1000;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1000/pci_fixup.c linux-2.4.20-pre7/arch/mips/au1000/pb1000/pci_fixup.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1000/pci_fixup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1000/pci_fixup.c	Thu Sep 12 20:01:39 2002
@@ -42,7 +42,7 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 void __init pcibios_fixup_resources(struct pci_dev *dev)
@@ -54,15 +54,15 @@
 {
 	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_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	au_writel(0, SDRAM_MBAR);        // set mbar to 0
+	au_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) |
+	au_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));
+	DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG));
 }
 
 void __init pcibios_fixup_irqs(void)
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1000/pci_ops.c linux-2.4.20-pre7/arch/mips/au1000/pb1000/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1000/pci_ops.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1000/pci_ops.c	Thu Sep 12 20:01:39 2002
@@ -46,18 +46,18 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 static struct resource pci_io_resource = {
-	"pci IO space", 
+	"pci IO space",
 	PCI_IO_START,
 	PCI_IO_END,
 	IORESOURCE_IO
 };
 
 static struct resource pci_mem_resource = {
-	"pci memory space", 
+	"pci memory space",
 	PCI_MEM_START,
 	PCI_MEM_END,
 	IORESOURCE_MEM
@@ -74,10 +74,10 @@
 
 /*
  * "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 
+ * 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, 
+static int config_access(unsigned char access_type, struct pci_dev *dev,
 			 unsigned char where, u32 * data)
 {
 	unsigned char bus = dev->bus->number;
@@ -92,18 +92,18 @@
 	config = PCI_CONFIG_BASE | (where & ~0x3);
 
 	if (access_type == PCI_ACCESS_WRITE) {
-		outl(*data, config);
+		au_writel(*data, config);
 	} else {
-		*data = inl(config);
+		*data = au_readl(config);
 	}
 	au_sync_udelay(1);
 
-	DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", 
+	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);
+	DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data);
 
-	if (inl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
+	if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) {
 		*data = 0xffffffff;
 		return -1;
 	} else {
@@ -119,7 +119,7 @@
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
 	*val = data & 0xff;
-	return ret; 
+	return ret;
 }
 
 
@@ -130,7 +130,7 @@
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
 	*val = data & 0xffff;
-	return ret; 
+	return ret;
 }
 
 static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
@@ -138,14 +138,14 @@
 	int ret;
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, val);
-	return ret; 
+	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;
 
@@ -164,11 +164,11 @@
 
 	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))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
 
 	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1000/setup.c linux-2.4.20-pre7/arch/mips/au1000/pb1000/setup.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1000/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1000/setup.c	Thu Sep 12 20:01:39 2002
@@ -67,7 +67,6 @@
 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(char *);
@@ -76,11 +75,7 @@
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
 
-
-void au1000_wbflush(void)
-{
-	__asm__ volatile ("sync");
-}
+void __init bus_error_init(void) { /* nothing */ }
 
 void __init au1000_setup(void)
 {
@@ -88,7 +83,7 @@
 	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 */
@@ -99,15 +94,14 @@
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
-#endif	  
+#endif
 
 	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. 
+	// IO/MEM resources.
 	set_io_port_base(0);
 	ioport_resource.start = 0x10000000;
 	ioport_resource.end = 0xffffffff;
@@ -121,8 +115,8 @@
 #endif
 
 	// set AUX clock to 12MHz * 8 = 96 MHz
-	outl(8, SYS_AUXPLL);
-	outl(0, SYS_PINSTATERD);
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
 
 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
@@ -138,19 +132,19 @@
 #endif
 
 	/* zero and disable FREQ2 */
-	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
-	outl(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* zero and disable USBH/USBD clocks */
-	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
-	outl(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
-	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 
-	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
 
 	switch (prid & 0x000000FF)
@@ -159,17 +153,17 @@
 	case 0x01: /* HA */
 	case 0x02: /* HB */
 	/* CPU core freq to 48MHz to slow it way down... */
-	outl(4, SYS_CPUPLL);
+	au_writel(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);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* CPU core freq to 384MHz */
-	outl(0x20, SYS_CPUPLL);
+	au_writel(0x20, SYS_CPUPLL);
 
 	printk("Au1000: 48MHz OHCI workaround enabled\n");
 		break;
@@ -177,7 +171,7 @@
 	default:  /* HC and newer */
 	// FREQ2 = aux/2 = 48 MHz
 	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-	outl(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 		break;
 	}
 
@@ -190,64 +184,69 @@
 #ifdef CONFIG_AU1000_USB_DEVICE
 	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
 #endif
-	outl(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
 #ifdef CONFIG_USB_OHCI
 	// enable host controller and wait for reset done
-	outl(0x08, USB_HOST_CONFIG);
+	au_writel(0x08, USB_HOST_CONFIG);
 	udelay(1000);
-	outl(0x0E, USB_HOST_CONFIG);
+	au_writel(0x0E, USB_HOST_CONFIG);
 	udelay(1000);
-	inl(USB_HOST_CONFIG); // throw away first read
-	while (!(inl(USB_HOST_CONFIG) & 0x10))
-		inl(USB_HOST_CONFIG);
+	au_readl(USB_HOST_CONFIG); // throw away first read
+	while (!(au_readl(USB_HOST_CONFIG) & 0x10))
+		au_readl(USB_HOST_CONFIG);
 #endif
-	
+
 	// configure pins GPIO[14:9] as GPIO
-	pin_func = inl(SYS_PINFUNC) & (u32)(~0x8080);
+	pin_func = au_readl(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);
+	au_writel(pin_func, SYS_PINFUNC);
+	au_writel(0x2800, SYS_TRIOUTCLR);
+	au_writel(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] 
+	// make gpio 15 an input (for interrupt line)
+	pin_func = au_readl(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);
+	au_writel(pin_func, SYS_PINFUNC);
+
+	au_writel(0x8000, SYS_TRIOUTCLR);
 
-	outl(0x8000, SYS_TRIOUTCLR);
-	
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
 
-	static_cfg0 = inl(MEM_STCFG0) & (u32)(~0xc00);
-	outl(static_cfg0, MEM_STCFG0);
+	static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
+	au_writel(static_cfg0, MEM_STCFG0);
 
 	// configure RCE2* for LCD
-	outl(0x00000004, MEM_STCFG2);
+	au_writel(0x00000004, MEM_STCFG2);
 
 	// MEM_STTIME2
-	outl(0x09000000, MEM_STTIME2);
+	au_writel(0x09000000, MEM_STTIME2);
 
 	// Set 32-bit base address decoding for RCE2*
-	outl(0x10003ff0, MEM_STADDR2);
+	au_writel(0x10003ff0, MEM_STADDR2);
 
 	// PCI CPLD setup
 	// expand CE0 to cover PCI
-	outl(0x11803e40, MEM_STADDR1);
+	au_writel(0x11803e40, MEM_STADDR1);
+
+	// burst visibility on
+	au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
 
-	// burst visibility on 
-	outl(inl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+	au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
+	au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
 
-	outl(0x83, MEM_STCFG1);         // ewait enabled, flash timing
-	outl(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
 
 #ifdef CONFIG_FB_E1356
 	if ((argptr = strstr(argptr, "video=")) == NULL) {
@@ -258,39 +257,35 @@
 
 
 #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_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	au_writel(0, SDRAM_MBAR);        // set mbar to 0
+	au_writel(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);
+	au_writel(0, UART0_ADDR + UART_CLK);
 #endif
-	outl(0, UART1_ADDR + UART_CLK);
-	outl(0, UART2_ADDR + UART_CLK);
-	outl(0, UART3_ADDR + UART_CLK);
+	au_writel(0, UART1_ADDR + UART_CLK);
+	au_writel(0, UART2_ADDR + UART_CLK);
+	au_writel(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);
+	au_writel(au_readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC);
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD
+	au_writel(pin_func, SYS_PINFUNC);
 
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
-	outl(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
 	au_sync();
-	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
-	outl(0, SYS_TOYTRIM);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
 
 	/* Enable Au1000 BCLK switching - note: sed1356 must not use
 	 * its BCLK (Au1000 LCLK) for any timings */
@@ -301,7 +296,7 @@
 	case 0x02: /* HB */
 		break;
 	default:  /* HC and newer */
-		outl(0x00000060, 0xb190003c);
+		au_writel(0x00000060, 0xb190003c);
 		break;
 	}
 }
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1100/Makefile linux-2.4.20-pre7/arch/mips/au1000/pb1100/Makefile
--- linux-2.4.20-pre6/arch/mips/au1000/pb1100/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1100/Makefile	Thu Sep 12 20:01:39 2002
@@ -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 Pb1100 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 := pb1100.o
+
+obj-y := init.o setup.o
+
+obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1100/init.c linux-2.4.20-pre7/arch/mips/au1000/pb1100/init.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1100/init.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1100/init.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,73 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1100 board setup
+ *
+ * Copyright 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/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 Pb1100";
+}
+
+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_PB1100;
+
+	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 -urN linux-2.4.20-pre6/arch/mips/au1000/pb1100/pci_fixup.c linux-2.4.20-pre7/arch/mips/au1000/pb1100/pci_fixup.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1100/pci_fixup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1100/pci_fixup.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,68 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Board specific pci fixups.
+ *
+ * Copyright 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/pb1100.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)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
+#endif
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1100/pci_ops.c linux-2.4.20-pre7/arch/mips/au1000/pb1100/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1100/pci_ops.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1100/pci_ops.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,57 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Pb1100 specific pci support.
+ *
+ * Copyright 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/pb1100.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
+
+struct pci_channel mips_pci_channels[] = {
+	{(struct pci_ops *) NULL, (struct resource *) NULL,
+	 (struct resource *) NULL, (int) NULL, (int) NULL}
+};
+
+#endif /* CONFIG_PCI */
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1100/setup.c linux-2.4.20-pre7/arch/mips/au1000/pb1100/setup.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1100/setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1100/setup.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,248 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Alchemy Pb1100 board setup.
+ *
+ * Copyright 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>
+#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/pb1100.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
+
+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 __init bus_error_init(void) { /* nothing */ }
+
+void __init au1100_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 Au1000 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
+
+	_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
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PININPUTEN);
+	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
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
+
+	/* zero and disable FREQ2 */
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD/IrDA clock */
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = au_readl(SYS_CLKSRC);
+	sys_clksrc &= ~0x0000001F;
+
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+	/*
+	 * Route 48MHz FREQ2 into USBH/USBD/IrDA
+	 */
+	sys_clksrc |= ((4<<2) | (0<<1) | 0 );
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* setup the static bus controller */
+	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
+	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+	// get USB Functionality pin state (device vs host drive pins)
+	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+#ifndef CONFIG_AU1000_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	au_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
+	au_writel(0x08, USB_HOST_CONFIG);
+	udelay(1000);
+	au_writel(0x0c, USB_HOST_CONFIG);
+	udelay(1000);
+	au_readl(USB_HOST_CONFIG);
+	while (!(au_readl(USB_HOST_CONFIG) & 0x10))
+	    ;
+	au_readl(USB_HOST_CONFIG);
+#endif
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_FB_AU1100
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		/* default panel */
+		strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");
+	}
+#endif
+
+#ifdef CONFIG_FB_E1356
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=e1356fb:system:pb1500");
+	}
+#endif
+
+#ifndef CONFIG_SERIAL_NONSTANDARD
+	/* don't touch the default serial console */
+	au_writel(0, UART0_ADDR + UART_CLK);
+#endif
+	au_writel(0, UART1_ADDR + UART_CLK);
+	au_writel(0, UART3_ADDR + UART_CLK);
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	au_sync();
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
+
+	au_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);
+		au_sync();
+	}
+	// Put the clock in BCD mode
+	if (readb(0xac00002C) & 0x4) { /* reg B */
+		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+		au_sync();
+	}
+#endif
+}
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1500/Makefile linux-2.4.20-pre7/arch/mips/au1000/pb1500/Makefile
--- linux-2.4.20-pre6/arch/mips/au1000/pb1500/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1500/Makefile	Thu Sep 12 20:01:39 2002
@@ -10,10 +10,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
 
 O_TARGET := pb1500.o
 
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1500/init.c linux-2.4.20-pre7/arch/mips/au1000/pb1500/init.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1500/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1500/init.c	Thu Sep 12 20:01:39 2002
@@ -34,7 +34,6 @@
 #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>
@@ -59,7 +58,7 @@
 	prom_envp = envp;
 
 	mips_machgroup = MACH_GROUP_ALCHEMY;
-	mips_machtype = MACH_PB1500;  
+	mips_machtype = MACH_PB1500;
 
 	prom_init_cmdline();
 	memsize_str = prom_getenv("memsize");
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1500/pci_fixup.c linux-2.4.20-pre7/arch/mips/au1000/pb1500/pci_fixup.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1500/pci_fixup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1500/pci_fixup.c	Thu Sep 12 20:01:39 2002
@@ -42,7 +42,7 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 static void fixup_resource(int r_num, struct pci_dev *dev) ;
@@ -57,8 +57,8 @@
 {
 	int i;
 	struct pci_dev *dev;
-	
-	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, 
+
+	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START,
 			Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
 
 	if (!virt_io_addr) {
@@ -103,7 +103,7 @@
 	return 0;
 }
 
-static void fixup_resource(int r_num, struct pci_dev *dev) 
+static void fixup_resource(int r_num, struct pci_dev *dev)
 {
 	unsigned long start, size, new_start;
 
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1500/pci_ops.c linux-2.4.20-pre7/arch/mips/au1000/pb1500/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1500/pci_ops.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1500/pci_ops.c	Thu Sep 12 20:01:39 2002
@@ -46,19 +46,19 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 /* TBD */
 static struct resource pci_io_resource = {
-	"pci IO space", 
+	"pci IO space",
 	Au1500_PCI_IO_START,
 	Au1500_PCI_IO_END,
 	IORESOURCE_IO
 };
 
 static struct resource pci_mem_resource = {
-	"pci memory space", 
+	"pci memory space",
 	Au1500_PCI_MEM_START,
 	Au1500_PCI_MEM_END,
 	IORESOURCE_MEM
@@ -73,7 +73,7 @@
 };
 
 static unsigned long cfg_addr;
-static int config_access(unsigned char access_type, struct pci_dev *dev, 
+static int config_access(unsigned char access_type, struct pci_dev *dev,
 			 unsigned char where, u32 * data)
 {
 	unsigned char bus = dev->bus->number;
@@ -82,7 +82,7 @@
 	unsigned long config, status;
 	static int first = 1;
 
-	/* 
+	/*
  	 * 7:3 = slot
  	 * 2:0 = function
 	 */
@@ -95,7 +95,7 @@
 	if (first) {
 		first = 0;
 		cfg_addr = ioremap(Au1500_EXT_CFG, 0x10000000);
-		if (!cfg_addr) 
+		if (!cfg_addr)
 			printk (KERN_ERR "PCI unable to ioremap cfg space\n");
 	}
 
@@ -110,13 +110,13 @@
 	}
 #endif
 
-	writel(((0x2000 << 16) | (readl(Au1500_PCI_STATCMD) & 0xffff)),
+	au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
 			Au1500_PCI_STATCMD);
-	//writel(readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG);
+	//au_writel(au_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 | 
+	config = cfg_addr |
 		((1<<device)<<11) | (function << 8) | (where & ~0x3);
 
 #if 0
@@ -125,18 +125,18 @@
 #endif
 
 	if (access_type == PCI_ACCESS_WRITE) {
-		writel(*data, config);
+		au_writel(*data, config);
 	} else {
-		*data = readl(config);
+		*data = au_readl(config);
 	}
 	au_sync_udelay(1);
 
-	DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n", 
+	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)) { 
+	status = au_readl(Au1500_PCI_STATCMD);
+	if (status & (1<<29)) {
 		*data = 0xffffffff;
 		return -1;
 	} else if ((status >> 28) & 0xf) {
@@ -159,7 +159,7 @@
         if (where & 1) data >>= 8;
         if (where & 2) data >>= 16;
         *val = data & 0xff;
-	return ret; 
+	return ret;
 }
 
 
@@ -171,7 +171,7 @@
 	ret = config_access(PCI_ACCESS_READ, dev, where, &data);
         if (where & 2) data >>= 16;
         *val = data & 0xffff;
-	return ret; 
+	return ret;
 }
 
 static int read_config_dword(struct pci_dev *dev, int where, u32 * val)
@@ -179,14 +179,14 @@
 	int ret;
 
 	ret = config_access(PCI_ACCESS_READ, dev, where, val);
-	return ret; 
+	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;
 
@@ -205,11 +205,11 @@
 
 	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))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
 
 	if (config_access(PCI_ACCESS_WRITE, dev, where, &data))
diff -urN linux-2.4.20-pre6/arch/mips/au1000/pb1500/setup.c linux-2.4.20-pre7/arch/mips/au1000/pb1500/setup.c
--- linux-2.4.20-pre6/arch/mips/au1000/pb1500/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/au1000/pb1500/setup.c	Thu Sep 12 20:01:39 2002
@@ -71,7 +71,6 @@
 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);
@@ -80,17 +79,14 @@
 extern struct resource iomem_resource;
 
 
-void au1500_wbflush(void)
-{
-	__asm__ volatile ("sync");
-}
+void __init bus_error_init(void) { /* nothing */ }
 
 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+ */
@@ -103,19 +99,18 @@
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
-#endif	  
+#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. 
+	// IO/MEM resources.
 	set_io_port_base(0);
 	ioport_resource.start = 0x10000000;
 	ioport_resource.end = 0xffffffff;
@@ -129,8 +124,8 @@
 #endif
 
 	// set AUX clock to 12MHz * 8 = 96 MHz
-	writel(8, SYS_AUXPLL);
-	outl(0, SYS_PINSTATERD);
+	au_writel(8, SYS_AUXPLL);
+	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
 
 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
@@ -146,24 +141,24 @@
 #endif
 
 	/* zero and disable FREQ2 */
-	sys_freqctrl = readl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
-	writel(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/* zero and disable USBH/USBD clocks */
-	sys_clksrc = readl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
-	writel(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
-	sys_freqctrl = readl(SYS_FREQCTRL0);
+	sys_freqctrl = au_readl(SYS_FREQCTRL0);
 	sys_freqctrl &= ~0xFFF00000;
 
-	sys_clksrc = readl(SYS_CLKSRC);
+	sys_clksrc = au_readl(SYS_CLKSRC);
 	sys_clksrc &= ~0x00007FE0;
 
 	// FREQ2 = aux/2 = 48 MHz
 	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
-	writel(sys_freqctrl, SYS_FREQCTRL0);
+	au_writel(sys_freqctrl, SYS_FREQCTRL0);
 
 	/*
 	 * Route 48MHz FREQ2 into USB Host and/or Device
@@ -174,30 +169,30 @@
 #ifdef CONFIG_AU1000_USB_DEVICE
 	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
 #endif
-	writel(sys_clksrc, SYS_CLKSRC);
+	au_writel(sys_clksrc, SYS_CLKSRC);
 
 
-	pin_func = readl(SYS_PINFUNC) & (u32)(~0x8000);
+	pin_func = au_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);
+	au_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);
+	au_writel(0x08, USB_HOST_CONFIG);
 	udelay(1000);
-	writel(0x0c, USB_HOST_CONFIG);
+	au_writel(0x0c, USB_HOST_CONFIG);
 	udelay(1000);
-	readl(USB_HOST_CONFIG);
-	while (!(readl(USB_HOST_CONFIG) & 0x10))
+	au_readl(USB_HOST_CONFIG);
+	while (!(au_readl(USB_HOST_CONFIG) & 0x10))
 	    ;
-	readl(USB_HOST_CONFIG);
+	au_readl(USB_HOST_CONFIG);
 #endif
-	
+
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
@@ -205,15 +200,20 @@
 #ifdef CONFIG_FB_E1356
 	if ((argptr = strstr(argptr, "video=")) == NULL) {
 		argptr = prom_getcmdline();
-		strcat(argptr, " video=e1356fb:system:pb1500,mmunalign:1");
+		strcat(argptr, " video=e1356fb:system:pb1500");
+	}
+#elif defined (CONFIG_FB_XPERT98)
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=atyfb:1024x768-8@70");
 	}
 #endif // CONFIG_FB_E1356
 
 #ifndef CONFIG_SERIAL_NONSTANDARD
 	/* don't touch the default serial console */
-	writel(0, UART0_ADDR + UART_CLK);
+	au_writel(0, UART0_ADDR + UART_CLK);
 #endif
-	writel(0, UART3_ADDR + UART_CLK);
+	au_writel(0, UART3_ADDR + UART_CLK);
 
 #ifdef CONFIG_BLK_DEV_IDE
 	ide_ops = &std_ide_ops;
@@ -221,35 +221,40 @@
 
 #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_writel(0, Au1500_PCI_CMEM);
+	au_writel(0x00003fff, Au1500_CFG_BASE);
+#if defined(__MIPSEB__)
+	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
+#else
+	au_writel(0xf, Au1500_PCI_CFG);
+#endif
+	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
+	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
+	au_writel(0x02a00356, Au1500_PCI_STATCMD);
+	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
+	au_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);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
 	au_sync();
-	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
-	outl(0, SYS_TOYTRIM);
+	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	au_writel(0, SYS_TOYTRIM);
 
 	/* Enable BCLK switching */
-	writel(0x00000060, 0xb190003c);
+	au_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);
+	// Enable the RTC if not already enabled
+	if (!(au_readl(0xac000028) & 0x20)) {
+		printk("enabling clock ...\n");
+		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
 	}
 	// Put the clock in BCD mode
-	if (readb(0xac00002C) & 0x4) { /* reg B */
-		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
+	if (readl(0xac00002C) & 0x4) { /* reg B */
+		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
 		au_sync();
 	}
 #endif
diff -urN linux-2.4.20-pre6/arch/mips/boot/Makefile linux-2.4.20-pre7/arch/mips/boot/Makefile
--- linux-2.4.20-pre6/arch/mips/boot/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/boot/Makefile	Thu Sep 12 20:01:39 2002
@@ -8,8 +8,6 @@
 
 USE_STANDARD_AS_RULE := true
 
-OBJS  = milo.o a.out.o
-
 #
 # Some DECstations need all possible sections of an ECOFF executable
 #
diff -urN linux-2.4.20-pre6/arch/mips/boot/addinitrd.c linux-2.4.20-pre7/arch/mips/boot/addinitrd.c
--- linux-2.4.20-pre6/arch/mips/boot/addinitrd.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/boot/addinitrd.c	Thu Sep 12 20:01:39 2002
@@ -82,7 +82,7 @@
 		die ("open initrd");
 	if (fstat (fd_initrd, &st) < 0)
 		die ("fstat initrd");
-	loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size) 
+	loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
 			+ MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
 	if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
 		loadaddr += MIPS_PAGE_SIZE;
diff -urN linux-2.4.20-pre6/arch/mips/boot/elf2ecoff.c linux-2.4.20-pre7/arch/mips/boot/elf2ecoff.c
--- linux-2.4.20-pre6/arch/mips/boot/elf2ecoff.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/boot/elf2ecoff.c	Thu Sep 12 20:01:39 2002
@@ -49,485 +49,106 @@
 /*
  * Some extra ELF definitions
  */
-#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
+#define PT_MIPS_REGINFO 0x70000000	/* Register usage information */
 
 /* -------------------------------------------------------------------- */
 
 struct sect {
-  unsigned long vaddr;
-  unsigned long len;
+	unsigned long vaddr;
+	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);
-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);
-void convert_elf_shdrs (Elf32_Shdr *, int);
-void convert_ecoff_filehdr(struct filehdr *);
-void convert_ecoff_aouthdr(struct aouthdr *);
-void convert_ecoff_esecs(struct scnhdr *, int);
-extern int errno;
 int *symTypeTable;
 int must_convert_endian = 0;
 int format_bigendian = 0;
 
-int
-main (int argc, char **argv, char **envp)
+static void copy(int out, int in, off_t offset, off_t size)
 {
-  Elf32_Ehdr ex;
-  Elf32_Phdr *ph;
-  Elf32_Shdr *sh;
-  char *shstrtab;
-  int i, pad;
-  struct sect text, data, bss;
-  struct filehdr efh;
-  struct aouthdr eah;
-  struct scnhdr esecs [6];
-  int infile, outfile;
-  unsigned long cur_vma = ULONG_MAX;
-  int addflag = 0;
-  int nosecs;
-
-  text.len = data.len = bss.len = 0;
-  text.vaddr = data.vaddr = bss.vaddr = 0;
-
-  /* Check args... */
-  if (argc < 3 || argc > 4)
-    {
-    usage:
-      fprintf (stderr,
-	       "usage: elf2aout <elf executable> <a.out executable> [-a]\n");
-      exit (1);
-    }
-  if (argc == 4)
-    {
-      if (strcmp (argv [3], "-a"))
-	goto usage;
-      addflag = 1;
-    }
-
-  /* Try the input file... */
-  if ((infile = open (argv [1], O_RDONLY)) < 0)
-    {
-      fprintf (stderr, "Can't open %s for read: %s\n",
-	       argv [1], strerror (errno));
-      exit (1);
-    }
-
-  /* Read the header, which is at the beginning of the file... */
-  i = read (infile, &ex, sizeof ex);
-  if (i != sizeof ex)
-    {
-      fprintf (stderr, "ex: %s: %s.\n",
-	       argv [1], i ? strerror (errno) : "End of file reached");
-      exit (1);
-    }
-
-  if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
-	format_bigendian = 1;
-
-  if (ntohs (0xaa55) == 0xaa55) {
-	if (!format_bigendian)
-		must_convert_endian = 1;
-  } else {
-	if (format_bigendian)
-		must_convert_endian = 1;
-  }
-  if (must_convert_endian)
-	convert_elf_hdr (&ex);
-
-  /* Read the program headers... */
-  ph = (Elf32_Phdr *)saveRead (infile, ex.e_phoff,
-				ex.e_phnum * sizeof (Elf32_Phdr), "ph");
-  if (must_convert_endian)
-	convert_elf_phdrs (ph, ex.e_phnum);
-  /* Read the section headers... */
-  sh = (Elf32_Shdr *)saveRead (infile, ex.e_shoff,
-				ex.e_shnum * sizeof (Elf32_Shdr), "sh");
-  if (must_convert_endian)
-	convert_elf_shdrs (sh, ex.e_shnum);
-  /* Read in the section string table. */
-  shstrtab = saveRead (infile, sh [ex.e_shstrndx].sh_offset,
-		       sh [ex.e_shstrndx].sh_size, "shstrtab");
-
-  /* Figure out if we can cram the program header into an ECOFF
-     header...  Basically, we can't handle anything but loadable
-     segments, but we can ignore some kinds of segments.  We can't
-     handle holes in the address space.  Segments may be out of order,
-     so we sort them first. */
-
-  qsort (ph, ex.e_phnum, sizeof (Elf32_Phdr), phcmp);
-
-  for (i = 0; i < ex.e_phnum; i++)
-    {
-      /* Section types we can ignore... */
-      if (ph [i].p_type == PT_NULL || ph [i].p_type == PT_NOTE ||
-	  ph [i].p_type == PT_PHDR || ph [i].p_type == PT_MIPS_REGINFO)
-	continue;
-      /* 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", 
-			  	ex.e_phnum, ph[i].p_type );
-	  exit (1);
-	}
-      /* Writable (data) segment? */
-      if (ph [i].p_flags & PF_W)
-	{
-	  struct sect ndata, nbss;
+	char ibuf[4096];
+	int remaining, cur, count;
 
-	  ndata.vaddr = ph [i].p_vaddr;
-	  ndata.len = ph [i].p_filesz;
-	  nbss.vaddr = ph [i].p_vaddr + ph [i].p_filesz;
-	  nbss.len = ph [i].p_memsz - ph [i].p_filesz;
+	/* Go to the start of the ELF symbol table... */
+	if (lseek(in, offset, SEEK_SET) < 0) {
+		perror("copy: lseek");
+		exit(1);
+	}
+
+	remaining = size;
+	while (remaining) {
+		cur = remaining;
+		if (cur > sizeof(ibuf))
+			cur = sizeof(ibuf);
+		remaining -= cur;
+		if ((count = read(in, ibuf, cur)) != cur) {
+			fprintf(stderr, "copy: read: %s\n",
+				count ? strerror(errno) :
+				"premature end of file");
+			exit(1);
+		}
+		if ((count = write(out, ibuf, cur)) != cur) {
+			perror("copy: write");
+			exit(1);
+		}
+	}
+}
 
-	  combine (&data, &ndata, 0);
-	  combine (&bss, &nbss, 1);
+/*
+ * Combine two segments, which must be contiguous.   If pad is true, it's
+ * okay for there to be padding between.
+ */
+static void combine(struct sect *base, struct sect *new, int pad)
+{
+	if (!base->len)
+		*base = *new;
+	else if (new->len) {
+		if (base->vaddr + base->len != new->vaddr) {
+			if (pad)
+				base->len = new->vaddr - base->vaddr;
+			else {
+				fprintf(stderr,
+					"Non-contiguous data can't be converted.\n");
+				exit(1);
+			}
+		}
+		base->len += new->len;
 	}
-      else
-	{
-	  struct sect ntxt;
+}
 
-	  ntxt.vaddr = ph [i].p_vaddr;
-	  ntxt.len = ph [i].p_filesz;
+static int phcmp(const void *v1, const void *v2)
+{
+	const Elf32_Phdr *h1 = v1;
+	const Elf32_Phdr *h2 = v2;
 
-	  combine (&text, &ntxt, 0);
-	}
-      /* Remember the lowest segment start address. */
-      if (ph [i].p_vaddr < cur_vma)
-	cur_vma = ph [i].p_vaddr;
-    }
-
-  /* Sections must be in order to be converted... */
-  if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
-      text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr)
-    {
-      fprintf (stderr, "Sections ordering prevents a.out conversion.\n");
-      exit (1);
-    }
-
-  /* If there's a data section but no text section, then the loader
-     combined everything into one section.   That needs to be the
-     text section, so just make the data section zero length following
-     text. */
-  if (data.len && !text.len)
-    {
-      text = data;
-      data.vaddr = text.vaddr + text.len;
-      data.len = 0;
-    }
-
-  /* If there is a gap between text and data, we'll fill it when we copy
-     the data, so update the length of the text segment as represented in
-     a.out to reflect that, since a.out doesn't allow gaps in the program
-     address space. */
-  if (text.vaddr + text.len < data.vaddr)
-    text.len = data.vaddr - text.vaddr;
-
-  /* We now have enough information to cons up an a.out header... */
-  eah.magic = OMAGIC;
-  eah.vstamp = 200;
-  eah.tsize = text.len;
-  eah.dsize = data.len;
-  eah.bsize = bss.len;
-  eah.entry = ex.e_entry;
-  eah.text_start = text.vaddr;
-  eah.data_start = data.vaddr;
-  eah.bss_start = bss.vaddr;
-  eah.gprmask = 0xf3fffffe;
-  memset (&eah.cprmask, '\0', sizeof eah.cprmask);
-  eah.gp_value = 0; /* unused. */
-
-  if (format_bigendian)
-    efh.f_magic = MIPSEBMAGIC;
-  else
-    efh.f_magic = MIPSELMAGIC;
-  if (addflag)
-    nosecs = 6;
-  else
-    nosecs = 3;
-  efh.f_nscns = nosecs;
-  efh.f_timdat = 0;	/* bogus */
-  efh.f_symptr = 0;
-  efh.f_nsyms = 0;
-  efh.f_opthdr = sizeof eah;
-  efh.f_flags = 0x100f; /* Stripped, not sharable. */
-
-  memset (esecs, 0, sizeof esecs);
-  strcpy (esecs [0].s_name, ".text");
-  strcpy (esecs [1].s_name, ".data");
-  strcpy (esecs [2].s_name, ".bss");
-  if (addflag) {
-    strcpy (esecs [3].s_name, ".rdata");
-    strcpy (esecs [4].s_name, ".sdata");
-    strcpy (esecs [5].s_name, ".sbss");
-  }
-  esecs [0].s_paddr = esecs [0].s_vaddr = eah.text_start;
-  esecs [1].s_paddr = esecs [1].s_vaddr = eah.data_start;
-  esecs [2].s_paddr = esecs [2].s_vaddr = eah.bss_start;
-  if (addflag) {
-    esecs [3].s_paddr = esecs [3].s_vaddr = 0;
-    esecs [4].s_paddr = esecs [4].s_vaddr = 0;
-    esecs [5].s_paddr = esecs [5].s_vaddr = 0;
-  }
-  esecs [0].s_size = eah.tsize;
-  esecs [1].s_size = eah.dsize;
-  esecs [2].s_size = eah.bsize;
-  if (addflag) {
-    esecs [3].s_size = 0;
-    esecs [4].s_size = 0;
-    esecs [5].s_size = 0;
-  }
-  esecs [0].s_scnptr = N_TXTOFF (efh, eah);
-  esecs [1].s_scnptr = N_DATOFF (efh, eah);
-#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
-#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
-  esecs [2].s_scnptr = esecs [1].s_scnptr +
-	  ECOFF_ROUND (esecs [1].s_size, ECOFF_SEGMENT_ALIGNMENT (&eah));
-  if (addflag) {
-    esecs [3].s_scnptr = 0;
-    esecs [4].s_scnptr = 0;
-    esecs [5].s_scnptr = 0;
-  }
-  esecs [0].s_relptr = esecs [1].s_relptr
-	  = esecs [2].s_relptr = 0;
-  esecs [0].s_lnnoptr = esecs [1].s_lnnoptr
-	  = esecs [2].s_lnnoptr = 0;
-  esecs [0].s_nreloc = esecs [1].s_nreloc = esecs [2].s_nreloc = 0;
-  esecs [0].s_nlnno = esecs [1].s_nlnno = esecs [2].s_nlnno = 0;
-  if (addflag) {
-    esecs [3].s_relptr = esecs [4].s_relptr 
-  	  = esecs [5].s_relptr = 0;
-    esecs [3].s_lnnoptr = esecs [4].s_lnnoptr
-	  = esecs [5].s_lnnoptr = 0;
-    esecs [3].s_nreloc = esecs [4].s_nreloc = esecs [5].s_nreloc = 0;
-    esecs [3].s_nlnno = esecs [4].s_nlnno = esecs [5].s_nlnno = 0;
-  }
-  esecs [0].s_flags = 0x20;
-  esecs [1].s_flags = 0x40;
-  esecs [2].s_flags = 0x82;
-  if (addflag) {
-    esecs [3].s_flags = 0x100;
-    esecs [4].s_flags = 0x200;
-    esecs [5].s_flags = 0x400;
-  }
-
-  /* Make the output file... */
-  if ((outfile = open (argv [2], O_WRONLY | O_CREAT, 0777)) < 0)
-    {
-      fprintf (stderr, "Unable to create %s: %s\n", argv [2], strerror (errno));
-      exit (1);
-    }
-
-  if (must_convert_endian)
-	convert_ecoff_filehdr (&efh);
-  /* Write the headers... */
-  i = write (outfile, &efh, sizeof efh);
-  if (i != sizeof efh)
-    {
-      perror ("efh: write");
-      exit (1);
-
-    for (i = 0; i < nosecs; i++)
-      {
-        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);
-      }
-    }
-  fprintf (stderr, "wrote %d byte file header.\n", i);
-
-  if (must_convert_endian)
-	convert_ecoff_aouthdr (&eah);
-  i = write (outfile, &eah, sizeof eah);
-  if (i != sizeof eah)
-    {
-      perror ("eah: write");
-      exit (1);
-    }
-  fprintf (stderr, "wrote %d byte a.out header.\n", i);
-
-  if (must_convert_endian)
-	convert_ecoff_esecs (&esecs[0], nosecs);
-  i = write (outfile, &esecs, nosecs * sizeof(struct scnhdr));
-  if (i != nosecs * sizeof(struct scnhdr))
-    {
-      perror ("esecs: write");
-      exit (1);
-    }
-  fprintf (stderr, "wrote %d bytes of section headers.\n", i);
-
-  if (pad = ((sizeof efh + sizeof eah + nosecs * sizeof(struct scnhdr)) & 15))
-    {
-      pad = 16 - pad;
-      i = write (outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
-      if (i < 0)
-	{
-	  perror ("ipad: write");
-	  exit (1);
-	}
-      fprintf (stderr, "wrote %d byte pad.\n", i);
-    }
+	if (h1->p_vaddr > h2->p_vaddr)
+		return 1;
+	else if (h1->p_vaddr < h2->p_vaddr)
+		return -1;
+	else
+		return 0;
+}
 
-  /* Copy the loadable sections.   Zero-fill any gaps less than 64k;
-     complain about any zero-filling, and die if we're asked to zero-fill
-     more than 64k. */
-  for (i = 0; i < ex.e_phnum; i++)
-    {
-      /* Unprocessable sections were handled above, so just verify that
-	 the section can be loaded before copying. */
-      if (ph [i].p_type == PT_LOAD && ph [i].p_filesz)
-	{
-	  if (cur_vma != ph [i].p_vaddr)
-	    {
-	      unsigned long gap = ph [i].p_vaddr - cur_vma;
-	      char obuf [1024];
-	      if (gap > 65536)
-		{
-		  fprintf (stderr, "Intersegment gap (%ld bytes) too large.\n",
-			   gap);
-		  exit (1);
-		}
-	      fprintf (stderr, "Warning: %ld byte intersegment gap.\n", gap);
-	      memset (obuf, 0, sizeof obuf);
-	      while (gap)
-		{
-		  int count = write (outfile, obuf, (gap > sizeof obuf
-						     ? sizeof obuf : gap));
-		  if (count < 0)
-		    {
-		      fprintf (stderr, "Error writing gap: %s\n",
-			       strerror (errno));
-		      exit (1);
-		    }
-		  gap -= count;
-		}
-	    }
-fprintf (stderr, "writing %d bytes...\n", ph [i].p_filesz);
-	  copy (outfile, infile, ph [i].p_offset, ph [i].p_filesz);
-	  cur_vma = ph [i].p_vaddr + ph [i].p_filesz;
-	}
-    }
-
-   /*
-     * Write a page of padding for boot PROMS that read entire pages.
-     * Without this, they may attempt to read past the end of the
-     * data section, incur an error, and refuse to boot.
-     */
-    {
-	char obuf[4096];
-	memset(obuf, 0, sizeof obuf);
-	if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
-	    fprintf(stderr, "Error writing PROM padding: %s\n",
-		    strerror(errno));
-	    exit(1);
-	}
-    }
-
-  /* Looks like we won... */
-  exit (0);
-}
-
-void
-copy (out, in, offset, size)
-     int out, in;
-     off_t offset, size;
-{
-  char ibuf [4096];
-  int remaining, cur, count;
-
-  /* Go to the start of the ELF symbol table... */
-  if (lseek (in, offset, SEEK_SET) < 0)
-    {
-      perror ("copy: lseek");
-      exit (1);
-    }
-
-  remaining = size;
-  while (remaining)
-    {
-      cur = remaining;
-      if (cur > sizeof ibuf)
-	cur = sizeof ibuf;
-      remaining -= cur;
-      if ((count = read (in, ibuf, cur)) != cur)
-	{
-	  fprintf (stderr, "copy: read: %s\n",
-		   count ? strerror (errno) : "premature end of file");
-	  exit (1);
+static char *saveRead(int file, off_t offset, off_t len, char *name)
+{
+	char *tmp;
+	int count;
+	off_t off;
+	if ((off = lseek(file, offset, SEEK_SET)) < 0) {
+		fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
+		exit(1);
 	}
-      if ((count = write (out, ibuf, cur)) != cur)
-	{
-	  perror ("copy: write");
-	  exit (1);
+	if (!(tmp = (char *) malloc(len))) {
+		fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
+			len);
+		exit(1);
 	}
-    }
-}
-
-/* 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;
-{
-  if (!base -> len)
-    *base = *new;
-  else if (new -> len)
-    {
-      if (base -> vaddr + base -> len != new -> vaddr)
-	{
-	  if (pad)
-	    base -> len = new -> vaddr - base -> vaddr;
-	  else
-	    {
-	      fprintf (stderr,
-		       "Non-contiguous data can't be converted.\n");
-	      exit (1);
-	    }
-	}
-      base -> len += new -> len;
-    }
-}
-
-int
-phcmp (h1, h2)
-     Elf32_Phdr *h1, *h2;
-{
-  if (h1 -> p_vaddr > h2 -> p_vaddr)
-    return 1;
-  else if (h1 -> p_vaddr < h2 -> p_vaddr)
-    return -1;
-  else
-    return 0;
-}
-
-char *saveRead (int file, off_t offset, off_t len, char *name)
-{
-  char *tmp;
-  int count;
-  off_t off;
-  if ((off = lseek (file, offset, SEEK_SET)) < 0)
-    {
-      fprintf (stderr, "%s: fseek: %s\n", name, strerror (errno));
-      exit (1);
-    }
-  if (!(tmp = (char *)malloc (len)))
-    {
-      fprintf (stderr, "%s: Can't allocate %ld bytes.\n", name, len);
-      exit (1);
-    }
-  count = read (file, tmp, len);
-  if (count != len)
-    {
-      fprintf (stderr, "%s: read: %s.\n",
-	       name, count ? strerror (errno) : "End of file reached");
-      exit (1);
-    }
-  return tmp;
+	count = read(file, tmp, len);
+	if (count != len) {
+		fprintf(stderr, "%s: read: %s.\n",
+			name,
+			count ? strerror(errno) : "End of file reached");
+		exit(1);
+	}
+	return tmp;
 }
 
 #define swab16(x) \
@@ -542,101 +163,450 @@
 		(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >>  8) | \
 		(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
 
-void convert_elf_hdr (Elf32_Ehdr *e)
+static void convert_elf_hdr(Elf32_Ehdr * e)
 {
-	e->e_type      = swab16(e->e_type);
-	e->e_machine   = swab16(e->e_machine);
-	e->e_version   = swab32(e->e_version);
-	e->e_entry     = swab32(e->e_entry);
-	e->e_phoff     = swab32(e->e_phoff);
-	e->e_shoff     = swab32(e->e_shoff);
-	e->e_flags     = swab32(e->e_flags);
-	e->e_ehsize    = swab16(e->e_ehsize);
+	e->e_type = swab16(e->e_type);
+	e->e_machine = swab16(e->e_machine);
+	e->e_version = swab32(e->e_version);
+	e->e_entry = swab32(e->e_entry);
+	e->e_phoff = swab32(e->e_phoff);
+	e->e_shoff = swab32(e->e_shoff);
+	e->e_flags = swab32(e->e_flags);
+	e->e_ehsize = swab16(e->e_ehsize);
 	e->e_phentsize = swab16(e->e_phentsize);
-	e->e_phnum     = swab16(e->e_phnum);
+	e->e_phnum = swab16(e->e_phnum);
 	e->e_shentsize = swab16(e->e_shentsize);
-	e->e_shnum     = swab16(e->e_shnum);
-	e->e_shstrndx  = swab16(e->e_shstrndx);
+	e->e_shnum = swab16(e->e_shnum);
+	e->e_shstrndx = swab16(e->e_shstrndx);
 }
 
-void convert_elf_phdrs (Elf32_Phdr *p, int num)
+static void convert_elf_phdrs(Elf32_Phdr * p, int num)
 {
 	int i;
 
-	for (i = 0; i < num; i++,p++) {
-		p->p_type   = swab32(p->p_type);
+	for (i = 0; i < num; i++, p++) {
+		p->p_type = swab32(p->p_type);
 		p->p_offset = swab32(p->p_offset);
-		p->p_vaddr  = swab32(p->p_vaddr);
-		p->p_paddr  = swab32(p->p_paddr);
+		p->p_vaddr = swab32(p->p_vaddr);
+		p->p_paddr = swab32(p->p_paddr);
 		p->p_filesz = swab32(p->p_filesz);
-		p->p_memsz  = swab32(p->p_memsz);
-		p->p_flags  = swab32(p->p_flags);
-		p->p_align  = swab32(p->p_align);
+		p->p_memsz = swab32(p->p_memsz);
+		p->p_flags = swab32(p->p_flags);
+		p->p_align = swab32(p->p_align);
 	}
 
 }
 
-void convert_elf_shdrs (Elf32_Shdr *s, int num)
+static void convert_elf_shdrs(Elf32_Shdr * s, int num)
 {
 	int i;
 
-	for (i = 0; i < num; i++,s++) {
-		s->sh_name      = swab32(s->sh_name);
-		s->sh_type      = swab32(s->sh_type);
-		s->sh_flags     = swab32(s->sh_flags);
-		s->sh_addr      = swab32(s->sh_addr);
-		s->sh_offset    = swab32(s->sh_offset);
-		s->sh_size      = swab32(s->sh_size);
-		s->sh_link      = swab32(s->sh_link);
-		s->sh_info      = swab32(s->sh_info);
+	for (i = 0; i < num; i++, s++) {
+		s->sh_name = swab32(s->sh_name);
+		s->sh_type = swab32(s->sh_type);
+		s->sh_flags = swab32(s->sh_flags);
+		s->sh_addr = swab32(s->sh_addr);
+		s->sh_offset = swab32(s->sh_offset);
+		s->sh_size = swab32(s->sh_size);
+		s->sh_link = swab32(s->sh_link);
+		s->sh_info = swab32(s->sh_info);
 		s->sh_addralign = swab32(s->sh_addralign);
-		s->sh_entsize   = swab32(s->sh_entsize);
+		s->sh_entsize = swab32(s->sh_entsize);
 	}
 }
 
-void convert_ecoff_filehdr(struct filehdr *f)
+static void convert_ecoff_filehdr(struct filehdr *f)
 {
-	f->f_magic  = swab16(f->f_magic);
-	f->f_nscns  = swab16(f->f_nscns);
+	f->f_magic = swab16(f->f_magic);
+	f->f_nscns = swab16(f->f_nscns);
 	f->f_timdat = swab32(f->f_timdat);
 	f->f_symptr = swab32(f->f_symptr);
-	f->f_nsyms  = swab32(f->f_nsyms);
+	f->f_nsyms = swab32(f->f_nsyms);
 	f->f_opthdr = swab16(f->f_opthdr);
-	f->f_flags  = swab16(f->f_flags);
+	f->f_flags = swab16(f->f_flags);
 }
 
-void convert_ecoff_aouthdr(struct aouthdr *a)
+static void convert_ecoff_aouthdr(struct aouthdr *a)
 {
-	a->magic      = swab16(a->magic);
-	a->vstamp     = swab16(a->vstamp);
-	a->tsize      = swab32(a->tsize);
-	a->dsize      = swab32(a->dsize);
-	a->bsize      = swab32(a->bsize);
-	a->entry      = swab32(a->entry);
+	a->magic = swab16(a->magic);
+	a->vstamp = swab16(a->vstamp);
+	a->tsize = swab32(a->tsize);
+	a->dsize = swab32(a->dsize);
+	a->bsize = swab32(a->bsize);
+	a->entry = swab32(a->entry);
 	a->text_start = swab32(a->text_start);
 	a->data_start = swab32(a->data_start);
-	a->bss_start  = swab32(a->bss_start);
-	a->gprmask    = swab32(a->gprmask);
+	a->bss_start = swab32(a->bss_start);
+	a->gprmask = swab32(a->gprmask);
 	a->cprmask[0] = swab32(a->cprmask[0]);
 	a->cprmask[1] = swab32(a->cprmask[1]);
 	a->cprmask[2] = swab32(a->cprmask[2]);
 	a->cprmask[3] = swab32(a->cprmask[3]);
-	a->gp_value   = swab32(a->gp_value);
+	a->gp_value = swab32(a->gp_value);
 }
 
-void convert_ecoff_esecs(struct scnhdr *s, int num)
+static void convert_ecoff_esecs(struct scnhdr *s, int num)
 {
 	int i;
 
 	for (i = 0; i < num; i++, s++) {
-		s->s_paddr   = swab32(s->s_paddr);
-		s->s_vaddr   = swab32(s->s_vaddr);
-		s->s_size    = swab32(s->s_size);
-		s->s_scnptr  = swab32(s->s_scnptr);
-		s->s_relptr  = swab32(s->s_relptr);
+		s->s_paddr = swab32(s->s_paddr);
+		s->s_vaddr = swab32(s->s_vaddr);
+		s->s_size = swab32(s->s_size);
+		s->s_scnptr = swab32(s->s_scnptr);
+		s->s_relptr = swab32(s->s_relptr);
 		s->s_lnnoptr = swab32(s->s_lnnoptr);
-		s->s_nreloc  = swab16(s->s_nreloc);
-		s->s_nlnno   = swab16(s->s_nlnno);
-		s->s_flags   = swab32(s->s_flags);
+		s->s_nreloc = swab16(s->s_nreloc);
+		s->s_nlnno = swab16(s->s_nlnno);
+		s->s_flags = swab32(s->s_flags);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	Elf32_Ehdr ex;
+	Elf32_Phdr *ph;
+	Elf32_Shdr *sh;
+	char *shstrtab;
+	int i, pad;
+	struct sect text, data, bss;
+	struct filehdr efh;
+	struct aouthdr eah;
+	struct scnhdr esecs[6];
+	int infile, outfile;
+	unsigned long cur_vma = ULONG_MAX;
+	int addflag = 0;
+	int nosecs;
+
+	text.len = data.len = bss.len = 0;
+	text.vaddr = data.vaddr = bss.vaddr = 0;
+
+	/* Check args... */
+	if (argc < 3 || argc > 4) {
+	      usage:
+		fprintf(stderr,
+			"usage: elf2aout <elf executable> <a.out executable> [-a]\n");
+		exit(1);
+	}
+	if (argc == 4) {
+		if (strcmp(argv[3], "-a"))
+			goto usage;
+		addflag = 1;
+	}
+
+	/* Try the input file... */
+	if ((infile = open(argv[1], O_RDONLY)) < 0) {
+		fprintf(stderr, "Can't open %s for read: %s\n",
+			argv[1], strerror(errno));
+		exit(1);
+	}
+
+	/* Read the header, which is at the beginning of the file... */
+	i = read(infile, &ex, sizeof(ex));
+	if (i != sizeof(ex)) {
+		fprintf(stderr, "ex: %s: %s.\n", argv[1],
+			i ? strerror(errno) : "End of file reached");
+		exit(1);
+	}
+
+	if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+		format_bigendian = 1;
+
+	if (ntohs(0xaa55) == 0xaa55) {
+		if (!format_bigendian)
+			must_convert_endian = 1;
+	} else {
+		if (format_bigendian)
+			must_convert_endian = 1;
+	}
+	if (must_convert_endian)
+		convert_elf_hdr(&ex);
+
+	/* Read the program headers... */
+	ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
+				     ex.e_phnum * sizeof(Elf32_Phdr), "ph");
+	if (must_convert_endian)
+		convert_elf_phdrs(ph, ex.e_phnum);
+	/* Read the section headers... */
+	sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
+				     ex.e_shnum * sizeof(Elf32_Shdr),
+				     "sh");
+	if (must_convert_endian)
+		convert_elf_shdrs(sh, ex.e_shnum);
+	/* Read in the section string table. */
+	shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
+			    sh[ex.e_shstrndx].sh_size, "shstrtab");
+
+	/* Figure out if we can cram the program header into an ECOFF
+	   header...  Basically, we can't handle anything but loadable
+	   segments, but we can ignore some kinds of segments.  We can't
+	   handle holes in the address space.  Segments may be out of order,
+	   so we sort them first. */
+
+	qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
+
+	for (i = 0; i < ex.e_phnum; i++) {
+		/* Section types we can ignore... */
+		if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
+		    ph[i].p_type == PT_PHDR
+		    || ph[i].p_type == PT_MIPS_REGINFO)
+			continue;
+		/* 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",
+				ex.e_phnum, ph[i].p_type);
+			exit(1);
+		}
+		/* Writable (data) segment? */
+		if (ph[i].p_flags & PF_W) {
+			struct sect ndata, nbss;
+
+			ndata.vaddr = ph[i].p_vaddr;
+			ndata.len = ph[i].p_filesz;
+			nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+			nbss.len = ph[i].p_memsz - ph[i].p_filesz;
+
+			combine(&data, &ndata, 0);
+			combine(&bss, &nbss, 1);
+		} else {
+			struct sect ntxt;
+
+			ntxt.vaddr = ph[i].p_vaddr;
+			ntxt.len = ph[i].p_filesz;
+
+			combine(&text, &ntxt, 0);
+		}
+		/* Remember the lowest segment start address. */
+		if (ph[i].p_vaddr < cur_vma)
+			cur_vma = ph[i].p_vaddr;
+	}
+
+	/* Sections must be in order to be converted... */
+	if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
+	    text.vaddr + text.len > data.vaddr
+	    || data.vaddr + data.len > bss.vaddr) {
+		fprintf(stderr,
+			"Sections ordering prevents a.out conversion.\n");
+		exit(1);
+	}
+
+	/*
+	 * If there's a data section but no text section, then the loader
+	 * combined everything into one section.   That needs to be the text
+	 * section, so just make the data section zero length following text.
+	 */
+	if (data.len && !text.len) {
+		text = data;
+		data.vaddr = text.vaddr + text.len;
+		data.len = 0;
+	}
+
+	/*
+	 * If there is a gap between text and data, we'll fill it when we copy
+	 * the data, so update the length of the text segment as represented in
+	 * a.out to reflect that, since a.out doesn't allow gaps in the program
+	 * address space.
+	 */
+	if (text.vaddr + text.len < data.vaddr)
+		text.len = data.vaddr - text.vaddr;
+
+	/* We now have enough information to cons up an a.out header... */
+	eah.magic = OMAGIC;
+	eah.vstamp = 200;
+	eah.tsize = text.len;
+	eah.dsize = data.len;
+	eah.bsize = bss.len;
+	eah.entry = ex.e_entry;
+	eah.text_start = text.vaddr;
+	eah.data_start = data.vaddr;
+	eah.bss_start = bss.vaddr;
+	eah.gprmask = 0xf3fffffe;
+	memset(&eah.cprmask, '\0', sizeof(eah.cprmask));
+	eah.gp_value = 0;	/* unused. */
+
+	if (format_bigendian)
+		efh.f_magic = MIPSEBMAGIC;
+	else
+		efh.f_magic = MIPSELMAGIC;
+	if (addflag)
+		nosecs = 6;
+	else
+		nosecs = 3;
+	efh.f_nscns = nosecs;
+	efh.f_timdat = 0;	/* bogus */
+	efh.f_symptr = 0;
+	efh.f_nsyms = 0;
+	efh.f_opthdr = sizeof(eah);
+	efh.f_flags = 0x100f;	/* Stripped, not sharable. */
+
+	memset(esecs, 0, sizeof(esecs));
+	strcpy(esecs[0].s_name, ".text");
+	strcpy(esecs[1].s_name, ".data");
+	strcpy(esecs[2].s_name, ".bss");
+	if (addflag) {
+		strcpy(esecs[3].s_name, ".rdata");
+		strcpy(esecs[4].s_name, ".sdata");
+		strcpy(esecs[5].s_name, ".sbss");
+	}
+	esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start;
+	esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start;
+	esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start;
+	if (addflag) {
+		esecs[3].s_paddr = esecs[3].s_vaddr = 0;
+		esecs[4].s_paddr = esecs[4].s_vaddr = 0;
+		esecs[5].s_paddr = esecs[5].s_vaddr = 0;
+	}
+	esecs[0].s_size = eah.tsize;
+	esecs[1].s_size = eah.dsize;
+	esecs[2].s_size = eah.bsize;
+	if (addflag) {
+		esecs[3].s_size = 0;
+		esecs[4].s_size = 0;
+		esecs[5].s_size = 0;
 	}
+	esecs[0].s_scnptr = N_TXTOFF(efh, eah);
+	esecs[1].s_scnptr = N_DATOFF(efh, eah);
+#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
+#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
+	esecs[2].s_scnptr = esecs[1].s_scnptr +
+	    ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah));
+	if (addflag) {
+		esecs[3].s_scnptr = 0;
+		esecs[4].s_scnptr = 0;
+		esecs[5].s_scnptr = 0;
+	}
+	esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0;
+	esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0;
+	esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0;
+	esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0;
+	if (addflag) {
+		esecs[3].s_relptr = esecs[4].s_relptr
+		    = esecs[5].s_relptr = 0;
+		esecs[3].s_lnnoptr = esecs[4].s_lnnoptr
+		    = esecs[5].s_lnnoptr = 0;
+		esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc =
+		    0;
+		esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0;
+	}
+	esecs[0].s_flags = 0x20;
+	esecs[1].s_flags = 0x40;
+	esecs[2].s_flags = 0x82;
+	if (addflag) {
+		esecs[3].s_flags = 0x100;
+		esecs[4].s_flags = 0x200;
+		esecs[5].s_flags = 0x400;
+	}
+
+	/* Make the output file... */
+	if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
+		fprintf(stderr, "Unable to create %s: %s\n", argv[2],
+			strerror(errno));
+		exit(1);
+	}
+
+	if (must_convert_endian)
+		convert_ecoff_filehdr(&efh);
+	/* Write the headers... */
+	i = write(outfile, &efh, sizeof(efh));
+	if (i != sizeof efh) {
+		perror("efh: write");
+		exit(1);
+	}
+
+	for (i = 0; i < nosecs; i++) {
+		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);
+	}
+	fprintf(stderr, "wrote %d byte file header.\n", i);
+
+	if (must_convert_endian)
+		convert_ecoff_aouthdr(&eah);
+	i = write(outfile, &eah, sizeof(eah));
+	if (i != sizeof(eah)) {
+		perror("eah: write");
+		exit(1);
+	}
+	fprintf(stderr, "wrote %d byte a.out header.\n", i);
+
+	if (must_convert_endian)
+		convert_ecoff_esecs(&esecs[0], nosecs);
+	i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr));
+	if (i != nosecs * sizeof(struct scnhdr)) {
+		perror("esecs: write");
+		exit(1);
+	}
+	fprintf(stderr, "wrote %d bytes of section headers.\n", i);
+
+	pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15;
+	if (pad) {
+		pad = 16 - pad;
+		i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
+		if (i < 0) {
+			perror("ipad: write");
+			exit(1);
+		}
+		fprintf(stderr, "wrote %d byte pad.\n", i);
+	}
+
+	/*
+	 * Copy the loadable sections.   Zero-fill any gaps less than 64k;
+	 * complain about any zero-filling, and die if we're asked to zero-fill
+	 * more than 64k.
+	 */
+	for (i = 0; i < ex.e_phnum; i++) {
+		/*
+		 * Unprocessable sections were handled above, so just verify
+		 * that the section can be loaded before copying.
+		 */
+		if (ph[i].p_type != PT_LOAD || ph[i].p_filesz == 0)
+			continue;
+
+		if (cur_vma != ph[i].p_vaddr) {
+			unsigned long gap = ph[i].p_vaddr - cur_vma;
+			char obuf[1024];
+
+			if (gap > 65536) {
+				fprintf(stderr, "Intersegment gap (%ld "
+				        "bytes) too large.\n", gap);
+				exit(1);
+			}
+			fprintf(stderr, "Warning: %ld byte intersegment gap.\n",
+					gap);
+			memset(obuf, 0, sizeof(obuf));
+			while (gap) {
+				int count = write(outfile, obuf,
+				   gap > sizeof(obuf) ?  sizeof(obuf) : gap);
+				if (count < 0) {
+					fprintf(stderr,
+						"Error writing gap: %s\n",
+						strerror(errno));
+					exit(1);
+				}
+				gap -= count;
+			}
+		}
+		fprintf(stderr, "writing %d bytes...\n", ph[i].p_filesz);
+		copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz);
+		cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
+	}
+
+	/*
+	 * Write a page of padding for boot PROMS that read entire pages.
+	 * Without this, they may attempt to read past the end of the
+	 * data section, incur an error, and refuse to boot.
+	 */
+	{
+		char obuf[4096];
+		memset(obuf, 0, sizeof(obuf));
+		if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
+			fprintf(stderr, "Error writing PROM padding: %s\n",
+				strerror(errno));
+			exit(1);
+		}
+	}
+
+	/* Looks like we won... */
+	exit(0);
 }
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/int-handler.S linux-2.4.20-pre7/arch/mips/cobalt/int-handler.S
--- linux-2.4.20-pre6/arch/mips/cobalt/int-handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/int-handler.S	Thu Sep 12 20:01:39 2002
@@ -26,8 +26,8 @@
 		SAVE_ALL
 		CLI
 		.set	at
-	
-		/* 
+
+		/*
 		 * Get pending Interrupts
 		 */
 		mfc0	s0,CP0_CAUSE	# get irq mask
@@ -52,30 +52,30 @@
 		j	ret_from_irq
 		 nop
 
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP3 */
 		 andi	a0,s0,CAUSEF_IP4
 
 		/* Ethernet 0 interrupt */
-		li	a0,4
+		li	a0,COBALT_RAQ_ETH0_IRQ
 		jal     do_IRQ
 		 move	a1,sp
 
 		j	ret_from_irq
 		 nop
 
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP4 */
 		 andi	a0,s0,CAUSEF_IP5
 
 		/* Ethernet 1 interrupt */
-		li	a0,13
+		li	a0,COBALT_RAQ_ETH1_IRQ
 		jal     do_IRQ
 		 move	a1,sp
 
 		j	ret_from_irq
 		 nop
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP5 */
 		 andi	a0,s0,CAUSEF_IP7
 
@@ -86,7 +86,7 @@
 
 		j	ret_from_irq
 		 nop
-1:	
+1:
 		beq	a0,zero,1f		/* Check IP7 */
 		  nop
 
@@ -100,4 +100,4 @@
 		 nop
 
 		END(cobalt_handle_int)
-	
+
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/irq.c linux-2.4.20-pre7/arch/mips/cobalt/irq.c
--- linux-2.4.20-pre6/arch/mips/cobalt/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/irq.c	Thu Sep 12 20:01:39 2002
@@ -42,11 +42,12 @@
  *    4   - Tulip 1
  *    5   - 16550 UART
  *    6   - VIA southbridge PIC
- *    7   - PCI
+ *    7   - unused
  *
- * The VIA chip is a master/slave 8259 setup and has the 
+ * The VIA chip is a master/slave 8259 setup and has the
  *  following interrupts
  *    8   - RTC
+ *    9   - PCI
  *    14  - IDE0
  *    15  - IDE1
  *
@@ -61,8 +62,8 @@
 
 #define COBALT_IRQS	16
 
-static unsigned short irqnr_to_type[COBALT_IRQS] = 
-{ CPUINT_LINE(0),  NOINT_LINE,      VIAINT_LINE,  NOINT_LINE, 
+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 };
@@ -116,102 +117,20 @@
 	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();
+	init_i8259_irqs();
 
 	/* 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);
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/pci.c linux-2.4.20-pre7/arch/mips/cobalt/pci.c
--- linux-2.4.20-pre6/arch/mips/cobalt/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/pci.c	Thu Sep 12 20:01:39 2002
@@ -19,9 +19,11 @@
 #include <asm/cobalt/cobalt.h>
 #include <asm/pci.h>
 #include <asm/io.h>
- 
+
 #ifdef CONFIG_PCI
 
+int cobalt_board_id;
+
 static void qube_expansion_slot_bist(struct pci_dev *dev)
 {
 	unsigned char ctrl;
@@ -56,6 +58,7 @@
 
 	/* Give it a working IRQ. */
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_QUBE_SLOT_IRQ);
+	dev->irq = COBALT_QUBE_SLOT_IRQ;
 
 	/* Fixup base addresses, we only support I/O at the moment. */
 	for(i = 0; i <= 5; i++) {
@@ -119,24 +122,22 @@
 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. */
+		if (cobalt_board_id == COBALT_BRD_ID_RAQ2) {
+			/* Setup the first Tulip on the RAQ */
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-                                              COBALT_QUBE_ETH_IRQ);
+					      COBALT_RAQ_ETH0_IRQ);
+			dev->irq = COBALT_RAQ_ETH0_IRQ;
 		} else {
-			/* Setup the first Tulip on the RAQ */
+			/* All Qube's route this the same way. */
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-                                              COBALT_RAQ_ETH0_IRQ);
+					      COBALT_QUBE_ETH_IRQ);
+			dev->irq = COBALT_QUBE_ETH_IRQ;
 		}
 		dev->resource[0].start = 0x100000;
 		dev->resource[0].end = 0x10007f;
@@ -156,6 +157,7 @@
 		/* Give it it's IRQ. */
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
                                       COBALT_RAQ_ETH1_IRQ);
+		dev->irq = COBALT_RAQ_ETH1_IRQ;
 
 		/* And finally, a usable I/O space allocation, right after what
 		 * the first Tulip uses.
@@ -168,15 +170,15 @@
 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);
+	dev->irq = COBALT_SCSI_IRQ;
 
-	if (cobalt_is_raq) {
+	if (cobalt_board_id == COBALT_BRD_ID_RAQ2) {
 
 		/* Enable the device. */
 		pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
@@ -186,7 +188,8 @@
 		pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
 
 		/* Give it it's RAQ IRQ. */
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 4);
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_RAQ_SCSI_IRQ);
+		dev->irq = COBALT_RAQ_SCSI_IRQ;
 
 		/* And finally, a usable I/O space allocation, right after what
 		 * the second Tulip uses.
@@ -252,11 +255,11 @@
 };
 
 
-static __inline__ int pci_range_ck(struct pci_dev *dev) 
+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) 
+       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  */
 
@@ -328,7 +331,7 @@
 
 static int
 qube_pci_write_config_word (struct pci_dev *dev,
-                                int where, 
+                                int where,
                                u16 val)
 {
 	unsigned long tmp;
@@ -347,7 +350,7 @@
 
 static int
 qube_pci_write_config_byte (struct pci_dev *dev,
-                                int where, 
+                                int where,
                                u8 val)
 {
 	unsigned long tmp;
@@ -374,8 +377,18 @@
 
 void __init pcibios_init(void)
 {
+	struct pci_dev dev;
+
 	printk("PCI: Probing PCI hardware\n");
 
+	/* Read the cobalt id register out of the PCI config space */
+	dev.devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
+	PCI_CFG_SET(&dev, (VIA_COBALT_BRD_ID_REG & ~0x3));
+	cobalt_board_id = *PCI_CFG_DATA >> ((VIA_COBALT_BRD_ID_REG & 3) * 8);
+	cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
+
+	printk("Cobalt Board ID: %d\n", cobalt_board_id);
+
 	ioport_resource.start = 0x00000000;
 	ioport_resource.end = 0x0fffffff;
 
@@ -393,7 +406,7 @@
 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);
@@ -409,7 +422,7 @@
 	panic("Uhhoh called pcibios_align_resource\n");
 }
 
-void pcibios_update_resource(struct pci_dev *dev, struct resource *root, 
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
 		struct resource *res, int resource)
 {
 
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/promcon.c linux-2.4.20-pre7/arch/mips/cobalt/promcon.c
--- linux-2.4.20-pre6/arch/mips/cobalt/promcon.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/promcon.c	Thu Sep 12 20:01:39 2002
@@ -70,7 +70,7 @@
 	ns16550_cons_put_char(kgdb_char, port);
 }
 
-static kdev_t 
+static kdev_t
 ns16550_console_dev(struct console *c)
 {
 	return MKDEV(TTY_MAJOR, 64 + c->index);
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/reset.c linux-2.4.20-pre7/arch/mips/cobalt/reset.c
--- linux-2.4.20-pre6/arch/mips/cobalt/reset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/reset.c	Thu Sep 12 20:01:39 2002
@@ -49,14 +49,14 @@
 	/* Blink our cute? little LED (number 3)... */
 	while (1) {
 		led_state = led_state | ( 1 << 3 );
-		LEDSet(led_state);  
+		LEDSet(led_state);
 		mark = jiffies;
 		while (jiffies<(mark+HZ));
 		led_state = led_state & ~( 1 << 3 );
 		LEDSet(led_state);
 		mark = jiffies;
 		while (jiffies<(mark+HZ));
-	} 
+	}
 }
 
 /*
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/setup.c linux-2.4.20-pre7/arch/mips/cobalt/setup.c
--- linux-2.4.20-pre6/arch/mips/cobalt/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/setup.c	Thu Sep 12 20:01:39 2002
@@ -35,7 +35,17 @@
 extern struct ide_ops std_ide_ops;
 
 
-char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 root=/dev/hda1" };
+char arcs_cmdline[CL_SIZE] = {
+ "console=ttyS0,115200 "
+#ifdef CONFIG_IP_PNP
+ "ip=on "
+#endif
+#ifdef CONFIG_ROOT_NFS
+ "root=/dev/nfs "
+#else
+ "root=/dev/hda1 "
+#endif
+ };
 
 const char *get_system_type(void)
 {
@@ -63,23 +73,19 @@
 	*timer_reg = 500000;
 
 	/* Register our timer interrupt */
-	setup_irq(0, irq);
+	setup_irq(COBALT_TIMER_IRQ, irq);
 
 	/* Enable timer ints */
-	*((volatile unsigned long *) GALILEO_TIMER_CTRL) = 
+	*((volatile unsigned long *) GALILEO_TIMER_CTRL) =
 			(unsigned long) (GALILEO_ENTC0 | GALILEO_SELTC0);
 	/* Unmask timer int */
-	*((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; 
+	*((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)
 {
 
@@ -95,21 +101,13 @@
 #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
@@ -117,7 +115,7 @@
 void __init prom_init(int argc)
 {
 	mips_machgroup = MACH_GROUP_COBALT;
-	
+
 	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
 }
 
diff -urN linux-2.4.20-pre6/arch/mips/cobalt/via.c linux-2.4.20-pre7/arch/mips/cobalt/via.c
--- linux-2.4.20-pre6/arch/mips/cobalt/via.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/cobalt/via.c	Thu Sep 12 20:01:39 2002
@@ -18,62 +18,30 @@
 
 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);
- 
+	outb(0x0C, 0x20);
+	mstat = inb(0x20);
+
 	if (mstat < 0) {
 		mstat &= 0x7f;
-		if (mstat != 2) {     	
+		if (mstat != 2) {
 			do_IRQ(mstat, regs);
-			VIA_PORT_WRITE(0x20, mstat | 0x20);
+			outb(mstat | 0x20, 0x20);
 		} else {
-			sstat = VIA_PORT_READ(0xA0);
+			sstat = inb(0xA0);
 
 			/* Slave interrupt */
-			VIA_PORT_WRITE(0xA0, 0x0C);
-			sstat = VIA_PORT_READ(0xA0);
-   
+			outb(0x0C, 0xA0);
+			sstat = inb(0xA0);
+
 			if (sstat < 0) {
 				do_IRQ((sstat + 8) & 0x7f, regs);
-				VIA_PORT_WRITE(0x20, 0x22);       
-				VIA_PORT_WRITE(0xA0, (sstat & 0x7f) | 0x20);
+				outb(0x22, 0x20);
+				outb((sstat & 0x7f) | 0x20, 0xA0);
 			} else {
 				printk("Spurious slave interrupt...\n");
 			}
@@ -87,13 +55,13 @@
 
 asmlinkage void galileo_irq(struct pt_regs *regs)
 {
-	unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE); 
+	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);
+		do_IRQ(COBALT_TIMER_IRQ, regs);
 	} else
 		printk("Spurious Galileo interrupt...\n");
 }
diff -urN linux-2.4.20-pre6/arch/mips/config-shared.in linux-2.4.20-pre7/arch/mips/config-shared.in
--- linux-2.4.20-pre6/arch/mips/config-shared.in	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/config-shared.in	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,803 @@
+mainmenu_name "Linux/MIPS 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 '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 Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32
+if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
+   bool '  Support for PCI AUTO Config' CONFIG_PCI_AUTO
+fi
+dep_bool 'Support for Alchemy Semi PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32
+dep_bool 'Support for Alchemy Semi PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32
+dep_bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL
+dep_bool 'Support for DECstations' CONFIG_DECSTATION $CONFIG_MIPS32
+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
+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
+dep_bool 'Support for MIPS SEAD board (EXPERIMENTAL)' CONFIG_MIPS_SEAD $CONFIG_EXPERIMENTAL
+bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT
+bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G
+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
+if [ "$CONFIG_DDB5477" = "y" ]; then
+   int '   bus frequency (in kHZ, 0 for auto-detect)' CONFIG_DDB5477_BUS_FREQUENCY 0
+fi
+bool 'Support for NEC Osprey board' CONFIG_NEC_OSPREY
+bool 'Support for NEC Eagle/Hawk board' CONFIG_NEC_EAGLE
+bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
+dep_bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO $CONFIG_MIPS32 $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 SGI-IP27 (Origin200/2000)' CONFIG_SGI_IP27 $CONFIG_MIPS64
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+   bool '  IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
+   bool '  Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+   bool '  NUMA Support' CONFIG_NUMA
+   bool '  Mapped kernel support' CONFIG_MAPPED_KERNEL
+   bool '  Kernel text replication support' CONFIG_REPLICATE_KTEXT
+   bool '  Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS
+   bool '  Multi-Processing support' CONFIG_SMP
+   #bool '  IP27 XXL' CONFIG_SGI_SN0_XXL
+fi
+dep_bool 'Support for SGI-IP32 (O2) (EXPERIMENTAL)' CONFIG_SGI_IP32 $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)' CONFIG_SIBYTE_SB1xxx_SOC $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
+   choice '   BCM1xxx SOC Type' \
+	  "BCM1250          CONFIG_SIBYTE_SB1250" BCM1250
+
+   bool '   Running under simulation' CONFIG_SIMULATION
+   bool '   Booting from CFE' CONFIG_SIBYTE_CFE
+   dep_bool '     Use firmware console' CONFIG_SIBYTE_CFE_CONSOLE $CONFIG_SIBYTE_CFE
+   if [ "$CONFIG_SIBYTE_CFE" = "n" ]; then
+      define_bool CONFIG_SIBYTE_STANDALONE y
+      int  '   Memory size (in megabytes)' CONFIG_SIBYTE_STANDALONE_RAM_SIZE 32
+   fi
+
+   bool '   Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
+   bool '   Support for ZBbus profiling' CONFIG_BCM1250_TBPROF
+
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      if [ "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then
+	 bool '   Multi-Processing support' CONFIG_SMP
+      fi
+   fi
+
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      bool '   Support for BCM1250/BCM112x onchip PCI controller' CONFIG_PCI
+   fi
+
+   if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then
+      bool '   Support for SWARM board' CONFIG_SIBYTE_SWARM
+   fi
+fi
+bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+dep_bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927 $CONFIG_MIPS32
+bool 'Support for ZAO Networks Capcella' CONFIG_ZAO_CAPCELLA
+
+dep_bool 'High Memory Support' CONFIG_HIGHMEM $CONFIG_MIPS32
+
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+#
+# Select some configuration options automatically based on user selections.
+#
+
+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_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_AU1000_USB_DEVICE y
+fi
+if [ "$CONFIG_MIPS_PB1100" = "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_PCI_AUTO n
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_AU1000_USB_DEVICE y
+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_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_AU1000_USB_DEVICE 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_I8259 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_MIPS_EV96100" = "y" ]; then
+   define_bool CONFIG_PCI 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_BOOT_ELF32 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   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
+   define_bool CONFIG_ARC32 y
+   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_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
+   define_bool CONFIG_I8259 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   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
+   define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_MIPS_SEAD" = "y" ]; then
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PCI n
+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_NONCOHERENT_IO y
+   define_bool CONFIG_OLD_TIME_C y
+fi
+if [ "$CONFIG_MOMENCO_OCELOT_G" = "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_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_NEW_TIME_C y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_PCI 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_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_PCI y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NEW_IRQ 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
+   define_bool CONFIG_I8259 y
+fi
+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_NEC_EAGLE" = "y" ]; then
+   define_bool CONFIG_CPU_VR41XX y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_VR41XX_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO 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_SGI_IP22" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_ARC_CONSOLE y
+   define_bool CONFIG_ARC_MEMORY y
+   define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_IRQ_CPU y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NONCOHERENT_IO y
+   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
+   define_bool CONFIG_SGI y
+fi
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+   define_bool CONFIG_BOOT_ELF64 y
+   define_bool CONFIG_ARC64 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_SGI_IP32" = "y" ]; then
+   define_bool CONFIG_ARC_MEMORY y
+   define_bool CONFIG_ARC32 y
+   #define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_int CONFIG_L1_CACHE_SHIFT 5
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+   define_bool CONFIG_PCI y
+fi
+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
+   define_bool CONFIG_BOOT_ELF32 y
+fi
+if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
+   define_bool CONFIG_ARC32 y
+   define_bool CONFIG_ARC_MEMORY 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
+if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then
+   define_bool CONFIG_CPU_VR41XX y
+   define_bool CONFIG_CPU_LITTLE_ENDIAN y
+   define_bool CONFIG_NEW_IRQ y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_VR41XX_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_ISA n
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_NEW_PCI y
+   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_DUMMY_KEYB y
+   define_bool CONFIG_SCSI n
+fi
+
+if [ "$CONFIG_MIPS_AU1000" != "y" ]; then
+   define_bool CONFIG_MIPS_AU1000 n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'CPU selection'
+
+choice 'CPU type' \
+	"MIPS32	CONFIG_CPU_MIPS32 \
+	 MIPS64	CONFIG_CPU_MIPS64 \
+	 R3000	CONFIG_CPU_R3000 \
+	 R39XX	CONFIG_CPU_TX39XX \
+	 R41xx	CONFIG_CPU_VR41XX \
+	 R4300	CONFIG_CPU_R4300 \
+	 R4x00	CONFIG_CPU_R4X00 \
+	 R49XX	CONFIG_CPU_TX49XX \
+	 R5000	CONFIG_CPU_R5000 \
+	 R5432	CONFIG_CPU_R5432 \
+	 R6000	CONFIG_CPU_R6000 \
+	 R52xx	CONFIG_CPU_NEVADA \
+	 R8000	CONFIG_CPU_R8000 \
+	 R10000	CONFIG_CPU_R10000 \
+	 RM7000	CONFIG_CPU_RM7000 \
+	 SB1	CONFIG_CPU_SB1" R4x00
+
+if [ "$CONFIG_CPU_R5000" = "y" ]; then
+   define_bool CONFIG_BOARD_SCACHE y
+fi
+
+if [ "$CONFIG_CPU_NEVADA" = "y" ]; then
+   define_bool CONFIG_BOARD_SCACHE y
+fi
+ 
+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
+   choice 'SB1 Pass' \
+	 "Pass1   CONFIG_CPU_SB1_PASS_1  \
+	  Pass2   CONFIG_CPU_SB1_PASS_2
+	  Pass2.2 CONFIG_CPU_SB1_PASS_2_2" Pass1
+   if [ "$CONFIG_CPU_SB1_PASS_1" = "y" ]; then
+      define_bool CONFIG_SB1_PASS_1_WORKAROUNDS y
+   fi
+   if [ "$CONFIG_CPU_SB1_PASS_2" = "y" ]; then
+      define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y
+   else
+      # Avoid prefetches on Pass 2 (before 2.2)
+      bool '  Enable prefetches' CONFIG_CPU_HAS_PREFETCH
+   fi
+   if [ "$CONFIG_CPU_SB1_PASS_2_2" = "y" ]; then
+      # XXXKW for now, let 2.2 use same WORKAROUNDS flag as pre-2.2
+      define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y
+   fi
+   bool '  Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR
+   dep_bool '    Ignore recoverable cache errors' CONFIG_SB1_CERR_IGNORE_RECOVERABLE $CONFIG_SB1_CACHE_ERROR
+   dep_bool '    Spin instead of running handler' CONFIG_SB1_CERR_SPIN $CONFIG_SB1_CACHE_ERROR
+   define_bool CONFIG_VTAG_ICACHE 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
+   dep_bool '  Support for 64-bit physical address space' CONFIG_64BIT_PHYS_ADDR $CONFIG_MIPS32
+fi
+
+dep_bool 'Override CPU Options' CONFIG_CPU_ADVANCED $CONFIG_MIPS32
+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" -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
+      else
+	 define_bool CONFIG_CPU_HAS_LLSC n
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
+	 define_bool CONFIG_CPU_HAS_WB n
+      fi
+   else
+      if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
+	 define_bool CONFIG_CPU_HAS_LLSC y
+	 define_bool CONFIG_CPU_HAS_LLDSCD n
+	 define_bool CONFIG_CPU_HAS_WB n
+      else
+	 define_bool CONFIG_CPU_HAS_LLSC y
+	 define_bool CONFIG_CPU_HAS_LLDSCD y
+	 define_bool CONFIG_CPU_HAS_WB n
+      fi
+   fi
+fi
+if [ "$CONFIG_CPU_R3000" = "y" ]; then
+   define_bool CONFIG_CPU_HAS_SYNC n
+else
+   define_bool CONFIG_CPU_HAS_SYNC y
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+if [ "$CONFIG_DECSTATION"  = "y" -o \
+     "$CONFIG_DDB5074"     = "y" -o \
+     "$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_TOSHIBA_JMR3927" = "y" ]; then
+   bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742
+fi
+
+if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
+   bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX
+   bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD
+fi
+
+if [ "$CONFIG_CPU_R10000" = "y" ]; then
+   dep_bool 'Support for large 64-bit configurations' CONFIG_MIPS_INSANE_LARGE $CONFIG_MIPS64
+fi
+
+if [ "$CONFIG_ARC32" = "y" ]; then
+   bool 'ARC console support' CONFIG_ARC_CONSOLE
+fi
+
+if [ "$CONFIG_SGI_IP22" = "y" ]; then
+   dep_bool 'Indigo-2 (IP22) EISA bus support' CONFIG_IP22_EISA $CONFIG_EXPERIMENTAL
+fi
+
+if [ "$CONFIG_IP22_EISA" = "y" ]; then
+   define_bool CONFIG_EISA y
+   bool '    ISA bus support' CONFIG_ISA
+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
+
+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
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+dep_bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT $CONFIG_MIPS64
+define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT
+
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000
+endmenu
+
+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
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+source drivers/telephony/Config.in
+
+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
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   source drivers/message/i2o/Config.in
+fi
+
+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
+
+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
+
+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
+   fi
+   endmenu
+fi
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
+source drivers/char/Config.in
+
+#source drivers/misc/Config.in
+
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'DECStation Character devices'
+
+   tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
+   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'
+   if [ "$CONFIG_VT" = "y" ]; then
+      tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
+      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
+	 define_bool CONFIG_FONT_8x16 y
+      fi
+      define_bool CONFIG_DUMMY_CONSOLE y
+   fi
+   endmenu
+fi
+
+source fs/Config.in
+
+source drivers/media/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
+comment 'Sound'
+
+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
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then
+   bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+   dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_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
+fi
+endmenu
+
+source lib/Config.in
diff -urN linux-2.4.20-pre6/arch/mips/config.in linux-2.4.20-pre7/arch/mips/config.in
--- linux-2.4.20-pre6/arch/mips/config.in	Thu Sep 12 20:01:30 2002
+++ linux-2.4.20-pre7/arch/mips/config.in	Thu Sep 12 20:01:39 2002
@@ -4,633 +4,6 @@
 #
 define_bool CONFIG_MIPS y
 define_bool CONFIG_MIPS32 y
+define_bool CONFIG_MIPS64 n
 
-mainmenu_name "Linux/MIPS 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 '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 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
-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
-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
-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 based on user selections.
-#
-
-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_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_MIPS_EV96100" = "y" ]; then
-   define_bool CONFIG_PCI 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
-   define_bool CONFIG_ARC32 y
-   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_NONCOHERENT_IO y
-   define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_OLD_TIME_C 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_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_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_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_PCI y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NEW_IRQ 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_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_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_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_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
-
-if [ "$CONFIG_MIPS_AU1000" != "y" ]; then
-   define_bool CONFIG_MIPS_AU1000 n
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'CPU selection'
-
-choice 'CPU type' \
-	"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" -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
-      else
-	 define_bool CONFIG_CPU_HAS_LLSC n
-	 define_bool CONFIG_CPU_HAS_LLDSCD n
-	 define_bool CONFIG_CPU_HAS_WB n
-      fi
-   else
-      if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
-	 define_bool CONFIG_CPU_HAS_LLSC y
-	 define_bool CONFIG_CPU_HAS_LLDSCD n
-	 define_bool CONFIG_CPU_HAS_WB n
-      else
-	 define_bool CONFIG_CPU_HAS_LLSC y
-	 define_bool CONFIG_CPU_HAS_LLDSCD y
-	 define_bool CONFIG_CPU_HAS_WB n
-      fi
-   fi
-fi
-endmenu
-
-mainmenu_option next_comment
-comment 'General setup'
-if [ "$CONFIG_DECSTATION" = "y" -o \
-     "$CONFIG_DDB5074" = "y" -o    \
-     "$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_TOSHIBA_JMR3927" = "y" ]; then
-       bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742
-fi
-
-if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
-   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
-
-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
-
-dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000
-endmenu
-
-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
-
-if [ "$CONFIG_NET" = "y" ]; then
-   source net/Config.in
-fi
-
-source drivers/telephony/Config.in
-
-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
-      define_bool CONFIG_BLK_DEV_IDE_MODES n
-      define_bool CONFIG_BLK_DEV_HD n
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'SCSI support'
-
-tristate 'SCSI support' CONFIG_SCSI
-
-if [ "$CONFIG_SCSI" != "n" ]; then
-   source drivers/scsi/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_PCI" = "y" ]; then
-   source drivers/message/i2o/Config.in
-fi
-
-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
-
-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
-
-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
-   fi
-   endmenu
-fi
-
-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'
-
-   tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL
-   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'
-   if [ "$CONFIG_VT" = "y" ]; then
-      tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE
-      if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then
-	 define_bool CONFIG_FONT_8x16 y
-      fi
-      define_bool CONFIG_DUMMY_CONSOLE y
-   fi
-   endmenu
-fi
-
-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
-comment 'Sound'
-
-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
-comment 'Kernel hacking'
-
-bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
-if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then
-  bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
-  dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_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
-fi
-endmenu
-
-source lib/Config.in
+source arch/mips/config-shared.in
diff -urN linux-2.4.20-pre6/arch/mips/ddb5074/Makefile linux-2.4.20-pre7/arch/mips/ddb5074/Makefile
--- linux-2.4.20-pre6/arch/mips/ddb5074/Makefile	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/ddb5074/Makefile	Thu Sep 12 20:01:39 2002
@@ -9,10 +9,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 = ddb5074.a
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5074/irq.c linux-2.4.20-pre7/arch/mips/ddb5074/irq.c
--- linux-2.4.20-pre6/arch/mips/ddb5074/irq.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/ddb5074/irq.c	Thu Sep 12 20:01:39 2002
@@ -60,9 +60,9 @@
 	 *
 	 *      IRQ1  - keyboard (default set by M1543)
 	 *      IRQ3  - reserved for UART B (default set by M1543) (note that
-	 *              the schematics for the DDB Vrc-5074 board seem to 
-	 *              indicate that IRQ3 is connected to the DS1386 
-	 *              watchdog timer interrupt output so we might have 
+	 *              the schematics for the DDB Vrc-5074 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)
@@ -71,7 +71,7 @@
 	 */
 
 	/*
-	 *  Assing mouse interrupt to IRQ12 
+	 *  Assing mouse interrupt to IRQ12
 	 */
 
 	/* Enter configuration mode */
diff -urN linux-2.4.20-pre6/arch/mips/ddb5074/setup.c linux-2.4.20-pre7/arch/mips/ddb5074/setup.c
--- linux-2.4.20-pre6/arch/mips/ddb5074/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5074/setup.c	Thu Sep 12 20:01:39 2002
@@ -25,6 +25,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/nile4.h>
 #include <asm/ddb5074.h>
+#include <asm/traps.h>
 
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -91,6 +92,10 @@
 		          IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init ddb_setup(void)
 {
 	extern int panic_timeout;
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/common/Makefile linux-2.4.20-pre7/arch/mips/ddb5xxx/common/Makefile
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/common/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/common/Makefile	Thu Sep 12 20:01:39 2002
@@ -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
 
 O_TARGET:= ddb5xxx.o
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/common/irq.c linux-2.4.20-pre7/arch/mips/ddb5xxx/common/irq.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/common/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/common/irq.c	Thu Sep 12 20:01:39 2002
@@ -13,6 +13,7 @@
  */
 #include <linux/config.h>
 #include <linux/init.h>
+#include <asm/irq.h>
 
 void (*irq_setup)(void);
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/common/nile4.c linux-2.4.20-pre7/arch/mips/ddb5xxx/common/nile4.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/common/nile4.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/common/nile4.c	Thu Sep 12 20:01:39 2002
@@ -16,14 +16,13 @@
  ***********************************************************************
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 u32
-ddb_calc_pdar(u32 phys, u32 size, int width, 
+ddb_calc_pdar(u32 phys, u32 size, int width,
 	      int on_memory_bus, int pci_visible)
 {
         u32 maskbits;
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/common/prom.c linux-2.4.20-pre7/arch/mips/ddb5xxx/common/prom.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/common/prom.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/common/prom.c	Thu Sep 12 20:01:39 2002
@@ -26,6 +26,8 @@
 
 char arcs_cmdline[CL_SIZE];
 
+void ddb5477_runtime_detection(void);
+
 const char *get_system_type(void)
 {
 	switch (mips_machtype) {
@@ -33,6 +35,8 @@
 	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";
+	case MACH_NEC_ROCKHOPPERII:	return "NEC RockhopperII";
+	default:			return "Unknown NEC board";
 	}
 }
 
@@ -92,6 +96,13 @@
            around just after that.
          */
 
+	/* We can only use the PCI bus to distinquish between
+	   the Rockhopper and RockhopperII backplanes and this must
+	   wait until ddb5477_board_init() in setup.c after the 5477
+	   is initialized.  So, until then handle
+	   both Rockhopper and RockhopperII backplanes as Rockhopper 1
+	 */
+
         test_offset = (char *)KSEG1ADDR(DEFAULT_LCS1_BASE + 0x800);
         saved_test_byte = *test_offset;
 
@@ -119,7 +130,7 @@
         *test_offset = saved_test_byte;
 
 	/* before we know a better way, we will trust PMON for getting
-	 * RAM size 
+	 * RAM size
 	 */
 	board_ram_size = 1 << (36 - (ddb_in32(DDB_SDRAM0) & 0xf));
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/common/rtc_ds1386.c linux-2.4.20-pre7/arch/mips/ddb5xxx/common/rtc_ds1386.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/common/rtc_ds1386.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/common/rtc_ds1386.c	Thu Sep 12 20:01:39 2002
@@ -24,6 +24,7 @@
 #include <asm/time.h>
 #include <asm/addrspace.h>
 
+#include <asm/mc146818rtc.h>
 #include <asm/debug.h>
 
 #define	EPOCH		2000
@@ -41,7 +42,7 @@
 
 static unsigned long
 rtc_ds1386_get_time(void)
-{	
+{
 	u8 byte;
 	u8 temp;
 	unsigned int year, month, day, hour, minute, second;
@@ -78,7 +79,7 @@
 	return mktime(year, month, day, hour, minute, second);
 }
 
-static int 
+static int
 rtc_ds1386_set_time(unsigned long t)
 {
 	struct rtc_time tm;
@@ -94,6 +95,7 @@
 	/* convert */
 	to_tm(t, &tm);
 
+
 	/* check each field one by one */
 	year = BIN_TO_BCD(tm.tm_year - EPOCH);
 	if (year != READ_RTC(0xA)) {
@@ -136,7 +138,7 @@
 	if (second != READ_RTC(0x1)) {
 		WRITE_RTC(0x1, second);
 	}
-	
+
 	return 0;
 }
 
@@ -144,7 +146,7 @@
 rtc_ds1386_init(unsigned long base)
 {
 	unsigned char byte;
-	
+
 	/* remember the base */
 	rtc_base = base;
 	db_assert((rtc_base & 0xe0000000) == KSEG1);
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/Makefile linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/Makefile
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/Makefile	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,18 @@
+#
+# 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...
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET = ddb5074.o
+
+obj-y				+= setup.o irq.o int-handler.o pci.o pci_ops.o nile4_pic.o time.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/int-handler.S linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/int-handler.S
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/int-handler.S	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,120 @@
+/*
+ *  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	s0, CP0_CAUSE		# get irq mask
+
+#if 1
+	mfc0	t2,CP0_STATUS		# get enabled interrupts
+	and	s0,t2			# isolate allowed ones
+#endif
+	/* First we check for r4k counter/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:
+	j	ret_from_irq
+	 nop
+	END(ddbIRQ)
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/irq.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/irq.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/irq.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,174 @@
+/*
+ *  arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 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/irq_cpu.h>
+#include <asm/ptrace.h>
+#include <asm/nile4.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+#include <asm/ddb5xxx/ddb5074.h>
+
+
+extern void __init i8259_init(void);
+extern void init_i8259_irqs (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);
+
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
+
+#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-5074 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
+	 *      IRQ12 - mouse
+	 */
+
+	/*
+	 *  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);
+
+	outb(0x30, M1543_PNP_INDEX);
+	printk("device 7, 0x30: %02x\n",inb(M1543_PNP_DATA));
+
+	outb(0x70, M1543_PNP_INDEX);
+	printk("device 7, 0x70: %02x\n",inb(M1543_PNP_DATA));
+
+	/* Leave configration mode */
+	outb(0xbb, M1543_PNP_CONFIG);
+
+
+}
+
+void ddb_local0_irqdispatch(struct pt_regs *regs)
+{
+	u32 mask;
+	int nile4_irq;
+
+	mask = nile4_get_irq_stat(0);
+
+	/* Handle the timer interrupt first */
+#if 0
+	if (mask & (1 << NILE4_INT_GPT)) {
+		do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
+		mask &= ~(1 << NILE4_INT_GPT);
+	}
+#endif
+	for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
+		if (mask & 1) {
+			if (nile4_irq == NILE4_INT_INTE) {
+				int i8259_irq;
+
+				nile4_clear_irq(NILE4_INT_INTE);
+				i8259_irq = nile4_i8259_iack();
+				do_IRQ(i8259_irq, regs);
+			} else
+				do_IRQ(nile4_to_irq(nile4_irq), regs);
+
+		}
+}
+
+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 __init ddb_irq_setup(void)
+{
+#ifdef CONFIG_REMOTE_DEBUG
+	if (remote_debug)
+		set_debug_traps();
+	breakpoint();		/* you may move this line to whereever you want :-) */
+#endif
+
+	/* setup cascade interrupts */
+	setup_irq(NILE4_IRQ_BASE  + NILE4_INT_INTE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
+
+	set_except_vector(0, ddbIRQ);
+
+	nile4_irq_setup(NILE4_IRQ_BASE);
+	m1543_irq_setup();
+	init_i8259_irqs();
+
+
+	printk("CPU_IRQ_BASE: %d\n",CPU_IRQ_BASE);
+
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+
+	printk("enabling 8259 cascade\n");
+
+	ddb5074_led_hex(0);
+
+	/* Enable the interrupt cascade */
+	nile4_enable_irq(NILE4_IRQ_BASE+IRQ_I8259_CASCADE);
+
+
+}
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/nile4_pic.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/nile4_pic.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/nile4_pic.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,288 @@
+/*
+ *  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 <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+static int irq_base;
+
+/*
+ *  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(unsigned int nile4_irq)
+{
+	u32 offset, t;
+
+	nile4_irq-=irq_base;
+
+	ddb5074_led_hex(8);
+
+	offset = DDB_INTCTRL;
+	if (nile4_irq >= 8) {
+		offset += 4;
+		nile4_irq -= 8;
+	}
+	ddb5074_led_hex(9);
+	t = ddb_in32(offset);
+	ddb5074_led_hex(0xa);
+	t |= 8 << (nile4_irq * 4);
+	ddb_out32(offset, t);
+	ddb5074_led_hex(0xb);
+}
+
+void nile4_disable_irq(unsigned int nile4_irq)
+{
+	u32 offset, t;
+
+	nile4_irq-=irq_base;
+
+	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)
+{
+	nile4_irq-=irq_base;
+	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 ;
+}
+
+static unsigned int nile4_irq_startup(unsigned int irq) {
+
+	nile4_enable_irq(irq);
+	return 0;
+
+}
+
+static void nile4_ack_irq(unsigned int irq) {
+
+    ddb5074_led_hex(4);
+
+	nile4_clear_irq(irq);
+    ddb5074_led_hex(2);
+	nile4_disable_irq(irq);
+
+    ddb5074_led_hex(0);
+}
+
+static void nile4_irq_end(unsigned int irq) {
+
+	ddb5074_led_hex(3);
+	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	ddb5074_led_hex(5);
+		nile4_enable_irq(irq);
+	ddb5074_led_hex(7);
+	}
+
+	ddb5074_led_hex(1);
+}
+
+#define nile4_irq_shutdown nile4_disable_irq
+
+static hw_irq_controller nile4_irq_controller = {
+    "nile4",
+    nile4_irq_startup,
+    nile4_irq_shutdown,
+    nile4_enable_irq,
+    nile4_disable_irq,
+    nile4_ack_irq,
+    nile4_irq_end,
+    NULL
+};
+
+void nile4_irq_setup(u32 base) {
+
+	int i;
+	extern irq_desc_t irq_desc[];
+
+	irq_base=base;
+
+	/* 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);
+	nile4_set_pci_irq_level_or_edge(4, 1);
+
+	/* PCI INTA#-D# must be active low, INTE# must be active high */
+	nile4_set_pci_irq_polarity(0, 0);
+	nile4_set_pci_irq_polarity(1, 0);
+	nile4_set_pci_irq_polarity(2, 0);
+	nile4_set_pci_irq_polarity(3, 0);
+	nile4_set_pci_irq_polarity(4, 1);
+
+
+	for (i = 0; i < 16; i++) {
+		nile4_clear_irq(i);
+		nile4_disable_irq(i);
+	}
+
+	/* Enable CPU int #0 */
+	nile4_enable_irq_output(0);
+
+	for (i= base; i< base + NUM_NILE4_INTERRUPTS; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &nile4_irq_controller;
+	}
+
+}
+
+#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 -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/pci.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/pci.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/pci.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/pci.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,130 @@
+#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}
+};
+
+#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
+
+#define     MAX_SLOT_NUM        14
+
+static unsigned char irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0 */ nile4_to_irq(PCI_EXT_INTE),
+	/* SLOT:  1 */ nile4_to_irq(PCI_EXT_INTA),
+	/* SLOT:  2 */ nile4_to_irq(PCI_EXT_INTA),
+	/* SLOT:  3 */ nile4_to_irq(PCI_EXT_INTB),
+	/* SLOT:  4 */ nile4_to_irq(PCI_EXT_INTC),
+	/* SLOT:  5 */ nile4_to_irq(NILE4_INT_UART),
+	/* SLOT:  6 */ 0xff,
+	/* SLOT:  7 */ 0xff,
+	/* SLOT:  8 */ 0xff,
+	/* SLOT:  9 */ 0xff,
+	/* SLOT:  10 */ nile4_to_irq(PCI_EXT_INTE),
+	/* SLOT:  11 */ 0xff,
+	/* SLOT:  12 */ 0xff,
+	/* SLOT:  13 */ nile4_to_irq(PCI_EXT_INTE),
+};
+
+void __init pcibios_fixup_irqs(void) {
+
+	struct pci_dev *dev;
+	int slot_num;
+
+	pci_for_each_dev(dev) {
+		slot_num = PCI_SLOT(dev->devfn);
+		db_assert(slot_num < MAX_SLOT_NUM);
+printk("irq_map[%d]: %02x\n",slot_num, irq_map[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];
+	}
+}
+
+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)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		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 */
+				pci_read_config_byte(dev, 0x7d, &t8);
+				t8 |= 0xc0;
+				pci_write_config_byte(dev, 0x7d, t8);
+				/* Turn LEDs D2 and D3 off */
+				pci_read_config_byte(dev, 0x7e, &t8);
+				t8 |= 0xc0;
+				pci_write_config_byte(dev, 0x7e, t8);
+
+		}
+	}
+}
+
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/pci_ops.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/pci_ops.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/pci_ops.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,342 @@
+/*
+ * 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) {
+		if (slot_num == 5) slot_num = 14;
+	}
+	else {
+		if (slot_num == 5) 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 = 0x00040000 << slot_num;
+	} else {
+		/* type 1 config */
+		pci_addr = 0x00040000 << slot_num;
+		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 -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/setup.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/setup.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/setup.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,275 @@
+/*
+ *  arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 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 <linux/ioport.h>
+#include <linux/irq.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/nile4.h>
+#include <asm/ddb5xxx/ddb5074.h>
+#include <asm/ddb5xxx/ddb5xxx.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 kbd_ops std_kbd_ops;
+extern struct rtc_ops ddb_rtc_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-5074 halted.\n");
+	do {
+	} while (1);
+}
+
+static void ddb_machine_power_off(void)
+{
+	printk("DDB Vrc-5074 halted. Please turn off the power.\n");
+	do {
+	} while (1);
+}
+
+extern void ddb_irq_setup(void);
+extern void rtc_ds1386_init(unsigned long base);
+
+extern void (*board_timer_setup) (struct irqaction * irq);
+
+void __init bus_error_init(void)
+{
+}
+
+static void __init ddb_timer_init(struct irqaction *irq)
+{
+	/* set the clock to 1 Hz */
+	nile4_out32(NILE4_T2CTRL, 1000000);
+	/* enable the General-Purpose Timer */
+	nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
+	/* reset timer */
+	nile4_out32(NILE4_T2CNTR, 0);
+	/* enable interrupt */
+	setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
+	nile4_enable_irq(nile4_to_irq(NILE4_INT_GPT));
+	change_cp0_status(ST0_IM,
+		          IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
+
+}
+
+static void __init ddb_time_init(void)
+{
+    /* we have ds1396 RTC chip */
+	rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE));
+}
+
+
+
+void __init ddb_setup(void)
+{
+	extern int panic_timeout;
+
+	irq_setup = ddb_irq_setup;
+	set_io_port_base(NILE4_PCI_IO_BASE);
+	isa_slot_offset = NILE4_PCI_MEM_BASE;
+	board_timer_setup = ddb_timer_init;
+	board_time_init = ddb_time_init;
+
+
+	_machine_restart = ddb_machine_restart;
+	_machine_halt = ddb_machine_halt;
+	_machine_power_off = ddb_machine_power_off;
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+#ifdef CONFIG_PC_KEYB
+    kbd_ops = &std_kbd_ops;
+#endif
+
+	rtc_ops = &ddb_rtc_ops;
+
+    ddb_out32(DDB_BAR0, 0);
+
+	ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, 0x10);
+	ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE , 0x10);
+
+#ifdef CONFIG_FB
+    conswitchp = &dummy_con;
+#endif
+
+	/* Reboot on panic */
+	panic_timeout = 180;
+}
+
+
+#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 ddb5074_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 ddb5074_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 ddb5074_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 -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/time.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/time.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5074/time.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5074/time.c	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,33 @@
+/*
+ *  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>
+#include <asm/ddb5xxx/ddb5074.h>
+#include <asm/ddb5xxx/ddb5xxx.h>
+
+
+static unsigned char ddb_rtc_read_data(unsigned long addr)
+{
+	return *(volatile unsigned char *)(KSEG1ADDR(DDB_PCI_MEM_BASE)+addr);
+}
+
+static void ddb_rtc_write_data(unsigned char data, unsigned long addr)
+{
+ 	*(volatile unsigned char *)(KSEG1ADDR(DDB_PCI_MEM_BASE)+addr)=data;
+}
+
+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 -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/Makefile linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/Makefile
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/Makefile	Thu Sep 12 20:01:39 2002
@@ -9,10 +9,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 = ddb5476.o
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/int-handler.S linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/int-handler.S
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/int-handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/int-handler.S	Thu Sep 12 20:01:39 2002
@@ -9,8 +9,6 @@
  * 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>
@@ -30,7 +28,7 @@
 	CLI
 	.set	at
 	.set	noreorder
-	mfc0	t0, CP0_CAUSE  
+	mfc0	t0, CP0_CAUSE
 	mfc0	t2, CP0_STATUS
 
 	and	t0, t2
@@ -64,13 +62,13 @@
 
 	.align	5
 
-ll_cpu_ip0:	
+ll_cpu_ip0:
 	li	a0, CPU_IRQ_BASE + 0
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip1:	
+ll_cpu_ip1:
 	li	a0, CPU_IRQ_BASE + 1
 	move	a1, sp
 	jal	do_IRQ
@@ -81,25 +79,25 @@
 	jal	vrc5476_irq_dispatch
 	j	ret_from_irq
 
-ll_cpu_ip3:	
+ll_cpu_ip3:
 	li	a0, CPU_IRQ_BASE + 3
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip4:	
+ll_cpu_ip4:
 	li	a0, CPU_IRQ_BASE + 4
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip5:	
+ll_cpu_ip5:
 	li	a0, CPU_IRQ_BASE + 5
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip6:	
+ll_cpu_ip6:
 	li	a0, CPU_IRQ_BASE + 6
 	move	a1, sp
 	jal	do_IRQ
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/irq.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/irq.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/irq.c	Thu Sep 12 20:01:39 2002
@@ -9,7 +9,6 @@
  * 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>
@@ -46,9 +45,9 @@
 	 *
 	 *      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 
+	 *              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)
@@ -60,7 +59,7 @@
 	 */
 
 	/*
-	 *  Assing mouse interrupt to IRQ12 
+	 *  Assing mouse interrupt to IRQ12
 	 */
 
 	/* Enter configuration mode */
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/nile4_pic.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	Thu Sep 12 20:01:39 2002
@@ -1,5 +1,5 @@
 /*
- *  arch/mips/ddb5476/nile4.c -- 
+ *  arch/mips/ddb5476/nile4.c --
  *  	low-level PIC code for NEC Vrc-5476 (Nile 4)
  *
  *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
@@ -9,6 +9,7 @@
  *  Author: jsun@mvista.com or jsun@junsun.net
  *
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/pci.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/pci.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/pci.c	Thu Sep 12 20:01:39 2002
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -9,13 +10,13 @@
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 static struct resource extpci_io_resource = {
-	"pci IO space", 
+	"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", 
+	"pci memory space",
 	DDB_PCI_MEM_BASE + 0x00100000,	/* leave 1 MB for RTC */
 	DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE -1,
 	IORESOURCE_MEM};
@@ -31,7 +32,7 @@
 /*
  * 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.
  */
 
@@ -92,7 +93,7 @@
 		db_assert(slot_num < MAX_SLOT_NUM);
 		db_assert(irq_map[slot_num] != 0xff);
 
-		pci_write_config_byte(dev, 
+		pci_write_config_byte(dev,
 				      PCI_INTERRUPT_LINE,
 				      irq_map[slot_num]);
 		dev->irq = irq_map[slot_num];
@@ -104,7 +105,7 @@
 #endif
 
 void __init ddb_pci_reset_bus(void)
-{	
+{
 	u32 temp;
 
 	/*
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/pci_ops.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/pci_ops.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/pci_ops.c	Thu Sep 12 20:01:39 2002
@@ -5,7 +5,7 @@
  * 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 
+ * 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
@@ -43,7 +43,7 @@
  * On DDB5476, we have one set of swap registers
  */
 struct pci_config_swap ext_pci_swap = {
-	DDB_PCIW0,  
+	DDB_PCIW0,
 	DDB_PCIINIT0,
 	DDB_PCI_CONFIG_BASE,
 	DDB_PCI_CONFIG_SIZE
@@ -53,7 +53,7 @@
 
 /*
  * 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)
@@ -66,7 +66,7 @@
 	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
@@ -77,7 +77,7 @@
 	} 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);
@@ -103,10 +103,10 @@
 		     0,		/* not on local memory bus */
 		     0);	/* not visible from PCI bus (N/A) */
 
-	/* 
-	 * calcuate the absolute pci config addr; 
+	/*
+	 * 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;
@@ -224,7 +224,7 @@
 	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; 
+	*(volatile u32*) (base + (func_num << 8) + where) = val;
 	ddb_close_config_base(swap);
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -314,7 +314,7 @@
 	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;
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/setup.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/setup.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/setup.c	Thu Sep 12 20:01:39 2002
@@ -25,6 +25,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/time.h>
 #include <asm/debug.h>
+#include <asm/traps.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -138,11 +139,15 @@
 	{ "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY}
 };
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 static void ddb5476_board_init(void);
 extern void ddb5476_irq_setup(void);
 extern void (*irq_setup)(void);
 
-void __init 
+void __init
 ddb_setup(void)
 {
 	extern int panic_timeout;
@@ -197,7 +202,7 @@
  * 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 
+static void
 ddb5476_board_init(void)
 {
 	/* ----------- setup PDARs ------------ */
@@ -240,7 +245,7 @@
 	/* 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_pci_reset_bus();
 
 	ddb_out32(DDB_BAR0, 0x00000008);
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	Thu Sep 12 20:01:39 2002
@@ -62,7 +62,7 @@
 	NULL				/* no affinity stuff for UP */
 };
 
-void __init 
+void __init
 vrc5476_irq_init(u32 base)
 {
 	extern irq_desc_t irq_desc[];
@@ -78,7 +78,7 @@
 }
 
 
-asmlinkage void 
+asmlinkage void
 vrc5476_irq_dispatch(struct pt_regs *regs)
 {
 	extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/Makefile linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/Makefile
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/Makefile	Thu Sep 12 20:01:39 2002
@@ -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
 
 O_TARGET:= ddb5477.o
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/debug.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/debug.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/debug.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/debug.c	Thu Sep 12 20:01:39 2002
@@ -30,9 +30,9 @@
 
 	printk("\nshow regs: %s\n", name);
 	for(i=0;regs[i].regname!= NULL; i++) {
-		printk("%-16s= %08x\t\t(@%08x)\n", 
-		       regs[i].regname, 
-		       *(unsigned *)(regs[i].regaddr), 
+		printk("%-16s= %08x\t\t(@%08x)\n",
+		       regs[i].regname,
+		       *(unsigned *)(regs[i].regaddr),
 		       regs[i].regaddr);
 	}
 }
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/int-handler.S linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/int-handler.S
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/int-handler.S	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/int-handler.S	Thu Sep 12 20:01:39 2002
@@ -9,8 +9,6 @@
  * 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>
@@ -28,14 +26,14 @@
 	CLI
 	.set	at
 	.set	noreorder
-	mfc0	t0, CP0_CAUSE  
+	mfc0	t0, CP0_CAUSE
 	mfc0	t2, CP0_STATUS
 
 	and	t0, t2
-       
+
 	andi	t1, t0, STATUSF_IP7	/* cpu timer */
 	bnez	t1, ll_cputimer_irq
-	andi	t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) 
+	andi	t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 )
 	bnez	t1, ll_vrc5477_irq
 	andi	t1, t0, STATUSF_IP0	/* software int 0 */
 	bnez	t1, ll_cpu_ip0
@@ -51,7 +49,7 @@
 
 	.align	5
 
-ll_vrc5477_irq:	
+ll_vrc5477_irq:
 	move	a0, sp
 	jal	vrc5477_irq_dispatch
 	j	ret_from_irq
@@ -63,13 +61,13 @@
 	j	ret_from_irq
 
 
-ll_cpu_ip0:	
+ll_cpu_ip0:
 	li	a0, 0
 	move	a1, sp
 	jal	do_IRQ
 	j	ret_from_irq
 
-ll_cpu_ip1:	
+ll_cpu_ip1:
 	li	a0, 1
 	move	a1, sp
 	jal	do_IRQ
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/irq.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/irq.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/irq.c	Thu Sep 12 20:01:39 2002
@@ -19,6 +19,8 @@
 #include <asm/system.h>
 #include <asm/mipsregs.h>
 #include <asm/debug.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -37,7 +39,7 @@
  *	7 - 	cpu timer (used by default)
  *
  *  8-39: 32 Vrc5477 interrupt sources
- *	(refer to the Vrc5477 manual)	
+ *	(refer to the Vrc5477 manual)
  */
 
 #define	PCI0			DDB_INTPPES0
@@ -55,7 +57,7 @@
 #define	INTD			3
 #define	INTE			4
 
-static inline void 
+static inline void
 set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
 {
 	u32 reg_value;
@@ -63,22 +65,25 @@
 
 	reg_value = ddb_in32(pci);
 	reg_bitmask = 0x3 << (intn * 2);
-	
+
 	reg_value &= ~reg_bitmask;
 	reg_value |= (active | trigger) << (intn * 2);
 	ddb_out32(pci, reg_value);
 }
 
+extern void init_i8259_irqs (void);
 extern void vrc5477_irq_init(u32 base);
 extern void mips_cpu_irq_init(u32 base);
 extern asmlinkage void ddb5477_handle_int(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
 
 void
 ddb5477_irq_setup(void)
 {
 	db_run(printk("ddb5477_irq_setup invoked.\n"));
 
-	/* by default, we disable all interrupts and route all vrc5477 
+	/* by default, we disable all interrupts and route all vrc5477
 	 * interrupts to pin 0 (irq 2) */
 	ddb_out32(DDB_INTCTRL0, 0);
 	ddb_out32(DDB_INTCTRL1, 0);
@@ -91,7 +96,10 @@
 	/* setup PCI interrupt attributes */
 	set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE);
-	set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII)
+		set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE);
+	else
+		set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE);
 
@@ -101,9 +109,9 @@
 	set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE);
 	set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE);
 
-	/* 
+	/*
 	 * for debugging purpose, we enable several error interrupts
-	 * and route them to pin 1. (IP3) 
+	 * and route them to pin 1. (IP3)
 	 */
 	/* cpu parity check - 0 */
 	ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0);
@@ -121,13 +129,34 @@
 	ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31);
 
 	/* init all controllers */
-	mips_cpu_irq_init(0);
-	vrc5477_irq_init(8);
+	init_i8259_irqs();
+	mips_cpu_irq_init(CPU_IRQ_BASE);
+	vrc5477_irq_init(VRC5477_IRQ_BASE);
+
+
+	/* setup cascade interrupts */
+	setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
+	setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);
 
 	/* hook up the first-level interrupt handler */
 	set_except_vector(0, ddb5477_handle_int);
 }
 
+u8 i8259_interrupt_ack(void)
+{
+	u8 irq;
+	u32 reg;
+
+	/* Set window 0 for interrupt acknowledge */
+	reg = ddb_in32(DDB_PCIINIT10);
+
+	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
+	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
+	ddb_out32(DDB_PCIINIT10, reg);
+
+	/* i8259.c set the base vector to be 0x0 */
+	return irq + I8259_IRQ_BASE;
+}
 /*
  * the first level int-handler will jump here if it is a vrc5477 irq
  */
@@ -154,10 +183,21 @@
 	}
 
 	intStatus = ddb_in32(DDB_INT0STAT);
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* check for i8259 interrupts */
+		if (intStatus & (1 << VRC5477_I8259_CASCADE)) {
+			int i8259_irq = i8259_interrupt_ack();
+			do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
+			return;
+		}
+	}
+
 	for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) {
 		/* do we need to "and" with the int mask? */
 		if (intStatus & bitmask) {
-			do_IRQ(8 + i, regs);
+			do_IRQ(VRC5477_IRQ_BASE + i, regs);
+			return;
 		}
 	}
 }
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/irq_5477.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/irq_5477.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/irq_5477.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/irq_5477.c	Thu Sep 12 20:01:39 2002
@@ -18,6 +18,7 @@
  * This file exports one function:
  *	vrc5477_irq_init(u32 irq_base);
  */
+
 #include <linux/interrupt.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
@@ -32,7 +33,7 @@
 static int vrc5477_irq_base = -1;
 
 
-static void 
+static void
 vrc5477_irq_enable(unsigned int irq)
 {
 	db_assert(vrc5477_irq_base != -1);
@@ -42,7 +43,7 @@
 	ll_vrc5477_irq_enable(irq - vrc5477_irq_base);
 }
 
-static void 
+static void
 vrc5477_irq_disable(unsigned int irq)
 {
 	db_assert(vrc5477_irq_base != -1);
@@ -99,7 +100,7 @@
 	NULL			/* no affinity stuff for UP */
 };
 
-void 
+void
 vrc5477_irq_init(u32 irq_base)
 {
 	extern irq_desc_t irq_desc[];
@@ -111,17 +112,8 @@
 		irq_desc[i].depth = 1;
 		irq_desc[i].handler = &vrc5477_irq_controller;
 	}
-	
-	vrc5477_irq_base = irq_base;
-}
 
-
-int vrc5477_irq_to_irq(int irq)
-{
-	db_assert(irq >= 0);
-	db_assert(irq < NUM_5477_IRQ);
-
-	return irq + vrc5477_irq_base;
+	vrc5477_irq_base = irq_base;
 }
 
 void ll_vrc5477_irq_route(int vrc5477_irq, int ip)
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/pci.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/pci.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/pci.c	Thu Sep 12 20:01:39 2002
@@ -11,36 +11,38 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 
+#include <asm/bootinfo.h>
 #include <asm/pci_channel.h>
 #include <asm/debug.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
 static struct resource extpci_io_resource = {
-	"ext pci IO space", 
-	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE,
+	"ext pci IO space",
+	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000,
 	DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE -1,
 	IORESOURCE_IO};
 
 static struct resource extpci_mem_resource = {
-	"ext pci memory space", 
-	DDB_PCI0_MEM_BASE,
+	"ext pci memory space",
+	DDB_PCI0_MEM_BASE + 0x100000,
 	DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE -1,
 	IORESOURCE_MEM};
 
 static struct resource iopci_io_resource = {
-	"io pci IO space", 
+	"io pci IO space",
 	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE,
 	DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE -1,
 	IORESOURCE_IO};
 
 static struct resource iopci_mem_resource = {
-	"ext pci memory space", 
+	"ext pci memory space",
 	DDB_PCI1_MEM_BASE,
 	DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE -1,
 	IORESOURCE_MEM};
@@ -59,79 +61,108 @@
  * we fix up irqs based on the slot number.
  * The first entry is at AD:11.
  * Fortunately this works because, although we have two pci buses,
- * they all have different slot numbers.
- * 
- * This does not work for devices on sub-buses.
+ * they all have different slot numbers (except for rockhopper slot 20
+ * which is handled below).
  *
- * Note that the irq number in the array is relative number in vrc5477.
- * We need to translate it to global irq number.
  */
 
 /*
- * irq mapping : PCI int # -> vrc5477 irq #
- * based on vrc5477 manual page 46
- */
-#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
-
-#define		PCI_IO_INTA		16
-#define		PCI_IO_INTB		17
-#define		PCI_IO_INTC		18
-#define		PCI_IO_INTD		19
-
-/* 
- * irq mapping : device -> pci int #, 
+ * irq mapping : device -> pci int # -> vrc4377 irq# ,
  * ddb5477 board manual page 4  and vrc5477 manual page 46
  */
-#define		INT_ONBOARD_TULIP	PCI_EXT_INTA
-#define		INT_SLOT1		PCI_EXT_INTB
-#define		INT_SLOT2		PCI_EXT_INTC
-#define		INT_SLOT3		PCI_EXT_INTD
-#define		INT_SLOT4		PCI_EXT_INTE
-
-#define		INT_USB_HOST		PCI_IO_INTA
-#define		INT_USB_PERI		PCI_IO_INTB
-#define		INT_AC97		PCI_IO_INTC
 
 /*
  * based on ddb5477 manual page 11
  */
 #define		MAX_SLOT_NUM		21
 static unsigned char irq_map[MAX_SLOT_NUM] = {
-	/* AD:11 */ 0xff, 0xff, 0xff, 0xff, 
-	/* AD:15 */ INT_ONBOARD_TULIP, INT_SLOT1, INT_SLOT2, INT_SLOT3,
-	/* AD:19 */ INT_SLOT4, 0xff, 0xff, 0xff,
-	/* AD:23 */ 0xff, 0xff, 0xff, 0xff,
-	/* AD:27 */ 0xff, 0xff, INT_AC97, INT_USB_PERI, 
-	/* AD:31 */ INT_USB_HOST
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ 0xff,
+	/* SLOT:  2, AD:13 */ 0xff,
+	/* SLOT:  3, AD:14 */ 0xff,
+	/* SLOT:  4, AD:15 */ VRC5477_IRQ_INTA,       /* onboard tulip */
+	/* SLOT:  5, AD:16 */ VRC5477_IRQ_INTB,       /* slot 1 */
+	/* SLOT:  6, AD:17 */ VRC5477_IRQ_INTC,       /* slot 2 */
+	/* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD,       /* slot 3 */
+	/* SLOT:  8, AD:19 */ VRC5477_IRQ_INTE,       /* slot 4 */
+	/* SLOT:  9, AD:20 */ 0xff,
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 0xff,
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0xff,
+	/* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
+	/* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
+	/* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
+};
+static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
+	/* SLOT:  0, AD:11 */ 0xff,
+	/* SLOT:  1, AD:12 */ VRC5477_IRQ_INTB,       /* onboard AMD PCNET */
+	/* SLOT:  2, AD:13 */ 0xff,
+	/* SLOT:  3, AD:14 */ 0xff,
+	/* SLOT:  4, AD:15 */ 14,                     /* M5229 ide ISA irq */
+	/* SLOT:  5, AD:16 */ VRC5477_IRQ_INTD,       /* slot 3 */
+	/* SLOT:  6, AD:17 */ VRC5477_IRQ_INTA,       /* slot 4 */
+	/* SLOT:  7, AD:18 */ VRC5477_IRQ_INTD,       /* slot 5 */
+	/* SLOT:  8, AD:19 */ 0,                      /* M5457 modem nop */
+	/* SLOT:  9, AD:20 */ VRC5477_IRQ_INTA,       /* slot 2 */
+	/* SLOT: 10, AD:21 */ 0xff,
+	/* SLOT: 11, AD:22 */ 0xff,
+	/* SLOT: 12, AD:23 */ 0xff,
+	/* SLOT: 13, AD:24 */ 0xff,
+	/* SLOT: 14, AD:25 */ 0xff,
+	/* SLOT: 15, AD:26 */ 0xff,
+	/* SLOT: 16, AD:27 */ 0xff,
+	/* SLOT: 17, AD:28 */ 0,                      /* M7101 PMU nop */
+	/* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
+	/* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
+	/* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
 };
 
-extern int vrc5477_irq_to_irq(int irq);
 void __init pcibios_fixup_irqs(void)
 {
         struct pci_dev *dev;
         int slot_num;
+        unsigned char *slot_irq_map;
+        unsigned char irq;
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII)
+		slot_irq_map = rockhopperII_irq_map;
+	else
+		slot_irq_map = irq_map;
+
 
 	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;
-               }
+		irq = slot_irq_map[slot_num];
 
 		db_assert(slot_num < MAX_SLOT_NUM);
-		db_assert(irq_map[slot_num] != 0xff);
 
-		pci_write_config_byte(dev, 
+                db_assert(irq != 0xff);
+
+		pci_write_config_byte(dev,
 				      PCI_INTERRUPT_LINE,
-				      irq_map[slot_num]);
-		dev->irq = vrc5477_irq_to_irq(irq_map[slot_num]);
+				      irq);
+
+		dev->irq = irq;
+
+		if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+			/* hack to distinquish overlapping slot 20s, one
+			 * on bus 0 (ALI USB on the M1535 on the backplane),
+			 * and one on bus 2 (NEC USB controller on the CPU board)
+			 * Make the M1535 USB - ISA IRQ number 9.
+			 */
+			if (slot_num == 20 && dev->bus->number == 0) {
+				pci_write_config_byte(dev,
+						      PCI_INTERRUPT_LINE,
+						      9);
+				dev->irq = 9;
+			}
+		}
+
 	}
 }
 
@@ -139,8 +170,8 @@
 extern void jsun_scan_pci_bus(void);
 extern void jsun_assign_pci_resource(void);
 #endif
-void __init ddb_pci_reset_bus(void)
-{	
+void ddb_pci_reset_bus(void)
+{
 	u32 temp;
 
 	/*
@@ -175,5 +206,43 @@
 
 void __init pcibios_fixup(void)
 {
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		struct pci_dev *dev;
+
+#define M1535_CONFIG_PORT 0x3f0
+#define M1535_INDEX_PORT  0x3f0
+#define M1535_DATA_PORT   0x3f1
+
+		printk("Configuring ALI M1535 Super I/O mouse irq.\n");
+
+		request_region(M1535_CONFIG_PORT, 2, "M1535 Super I/O config");
+
+		/* Enter config mode. */
+		outb(0x51, M1535_CONFIG_PORT);
+		outb(0x23, M1535_CONFIG_PORT);
+
+		/* Select device 0x07. */
+		outb(0x07, M1535_INDEX_PORT);
+		outb(0x07, M1535_DATA_PORT);
+
+		/* Set mouse irq (register 0x72) to 12. */
+		outb(0x72, M1535_INDEX_PORT);
+		outb(0x0c, M1535_DATA_PORT);
+
+		/* Exit config mode. */
+		outb(0xbb, M1535_CONFIG_PORT);
+
+		pci_for_each_dev(dev) {
+			if(dev->vendor == PCI_VENDOR_ID_AL)
+				if(dev->device == PCI_DEVICE_ID_AL_M1535
+				    || dev->device == PCI_DEVICE_ID_AL_M1533) {
+				u8 old;
+				printk("Enabling ALI M1533/35 PS2 keyboard/mouse.\n");
+				pci_read_config_byte(dev, 0x41, &old);
+				pci_write_config_byte(dev, 0x41, old | 0xd0);
+			}
+		}
+
+	}
 }
 
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/pci_ops.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/pci_ops.c	Thu Sep 12 20:01:39 2002
@@ -5,7 +5,7 @@
  * arch/mips/ddb5xxx/ddb5477/pci_ops.c
  *     Define the pci_ops for DB5477.
  *
- * Much of the code is derived from the original DDB5074 port by 
+ * 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
@@ -48,13 +48,13 @@
  * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI.
  */
 struct pci_config_swap ext_pci_swap = {
-	DDB_PCIW0,  
+	DDB_PCIW0,
 	DDB_PCIINIT00,
 	DDB_PCI0_CONFIG_BASE,
 	DDB_PCI0_CONFIG_SIZE
 };
 struct pci_config_swap io_pci_swap = {
-	DDB_IOPCIW0,  
+	DDB_IOPCIW0,
 	DDB_PCIINIT01,
 	DDB_PCI1_CONFIG_BASE,
 	DDB_PCI1_CONFIG_SIZE
@@ -63,7 +63,7 @@
 
 /*
  * 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)
@@ -91,10 +91,10 @@
 		     0,		/* not on local memory bus */
 		     0);	/* not visible from PCI bus (N/A) */
 
-	/* 
-	 * calcuate the absolute pci config addr; 
+	/*
+	 * 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;
@@ -211,7 +211,7 @@
 	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; 
+	*(volatile u32*) (base + (func_num << 8) + where) = val;
 	ddb_close_config_base(swap);
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -300,114 +300,3 @@
 	iopci_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;
-
-	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< 2; j++) {
-		if (j ==  0) {
-			printk("scan ddb5477 external PCI bus:\n");
-			bus.ops = &ddb5477_ext_pci_ops;
-		} else {
-			printk("scan ddb5477 IO PCI bus:\n");
-			bus.ops = &ddb5477_io_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("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++) {
-				db_verify(pci_read_config_dword(&dev, i*4, &temp),
-					  == PCIBIOS_SUCCESSFUL);
-				printk("\t%08X", temp);
-				if ((i%4) == 3) printk("\n");
-			}
-		}
-	}
-}
-
-
-static void jsun_hardcode_pci_resources_eepro(void)
-{
-	struct pci_bus bus;
-	struct pci_dev dev;
-	u32 temp;
-
-	bus.parent = NULL;	/* we scan the top level only */
-	bus.ops = &ddb5477_ext_pci_ops;
-	dev.bus = &bus;
-	dev.sysdata = NULL;
-
-	/* for slot 5 (ext pci 1) eepro card */
-	dev.devfn = 5*8;
-	pci_read_config_dword(&dev, 0, &temp);
-	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);
-	pci_write_config_dword(&dev, PCI_BASE_ADDRESS_2, DDB_PCI0_MEM_BASE+0x100000);
-	pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 17);
-}
-
-static void jsun_hardcode_pci_resources_onboard_tulip(void)
-{
-	struct pci_bus bus;
-	struct pci_dev dev;
-	u32 temp;
-
-	bus.parent = NULL;	/* we scan the top level only */
-	bus.ops = &ddb5477_ext_pci_ops;
-	dev.bus = &bus;
-	dev.sysdata = NULL;
-
-	/* for slot 4 on board ether chip */
-	dev.devfn = 4*8;
-	pci_read_config_dword(&dev, 0, &temp);
-	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);
-	pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 16);
-}
-
-static void jsun_hardcode_pci_resources(void)
-{
-	jsun_hardcode_pci_resources_onboard_tulip();
-}
-
-void jsun_assign_pci_resource(void)
-{
-	jsun_hardcode_pci_resources();
-}
-
-#endif
diff -urN linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/setup.c linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/setup.c
--- linux-2.4.20-pre6/arch/mips/ddb5xxx/ddb5477/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/ddb5xxx/ddb5477/setup.c	Thu Sep 12 20:01:39 2002
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/param.h>	/* for HZ */
 
+#include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
@@ -31,7 +32,11 @@
 #include <asm/irq.h>
 #include <asm/reboot.h>
 #include <asm/gdb-stub.h>
+#include <asm/traps.h>
 #include <asm/debug.h>
+#ifdef CONFIG_PC_KEYB
+#include <asm/keyboard.h>
+#endif
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -40,15 +45,13 @@
 
 // #define	USE_CPU_COUNTER_TIMER	/* whether we use cpu counter */
 
-#ifdef USE_CPU_COUNTER_TIMER
-#define	CPU_COUNTER_FREQUENCY		83000000
-#else
-/* otherwise we use special timer 1 */
-#define	SP_TIMER_FREQUENCY		83000000
+#ifndef USE_CPU_COUNTER_TIMER
 #define	SP_TIMER_BASE			DDB_SPT1CTRL_L
-#define	SP_TIMER_IRQ			(8 + 6)
+#define	SP_TIMER_IRQ			VRC5477_IRQ_SPT1
 #endif
 
+static int bus_frequency = CONFIG_DDB5477_BUS_FREQUENCY*1000;
+
 static void ddb_machine_restart(char *command)
 {
 	static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
@@ -79,19 +82,71 @@
 	while (1);
 }
 
+static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+{
+	unsigned int freq;
+	unsigned char c;
+	unsigned int t1, t2;
+	unsigned i;
+	unsigned preset_freq[]={
+		0,        83330000, 100000000, 124000000,133300000, 0xffffffff};
+
+	ddb_out32(SP_TIMER_BASE, 0xffffffff);
+	ddb_out32(SP_TIMER_BASE+4, 0x1);
+	ddb_out32(SP_TIMER_BASE+8, 0xffffffff);
+	c= *(volatile unsigned char*)rtc_base;
+	for(i=0; (i<100000000) && (c == *(volatile unsigned char*)rtc_base); i++);
+
+	if (c == *(volatile unsigned char*)rtc_base) {
+		printk("Failed to detect bus frequency.  Use default 83.3MHz.\n");
+		return 83333000;
+	}
+
+	/* we are now at the turn of 1/100th second */
+	t1 = ddb_in32(SP_TIMER_BASE+8);
+
+	c= *(volatile unsigned char*)rtc_base;
+	while (c == *(volatile unsigned char*)rtc_base);
+
+	/* we are now at the turn of another 1/100th second */
+	t2 = ddb_in32(SP_TIMER_BASE+8);
+	ddb_out32(SP_TIMER_BASE+4, 0x0);	/* disable it again */
+	freq = (t1 - t2)*100;
+
+	/* find the nearest preset freq */
+	for (i=0; freq > preset_freq[i+1]; i++);
+	if ((freq - preset_freq[i]) >= (preset_freq[i+1]-freq))
+		i++;
+
+	printk("DDB bus frequency detection : %d -> %d\n", freq, preset_freq[i]);
+	return preset_freq[i];
+}
+
 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
+	unsigned long rtc_base;
+	unsigned int i;
 
 	/* we have ds1396 RTC chip */
-	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
-		rtc_ds1386_init(KSEG1ADDR(DDB_LCS2_BASE));
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		rtc_base = KSEG1ADDR(DDB_LCS2_BASE);
 	} else {
-		rtc_ds1386_init(KSEG1ADDR(DDB_LCS1_BASE));
+		rtc_base = KSEG1ADDR(DDB_LCS1_BASE);
+	}
+	rtc_ds1386_init(rtc_base);
+
+	/* do we need to do run-time detection of bus speed? */
+	if (bus_frequency == 0) {
+		bus_frequency = detect_bus_frequency(rtc_base);
 	}
+
+	/* mips_counter_frequency is 1/2 of the cpu core freq */
+	i =  (read_32bit_cp0_register(CP0_CONFIG) >> 28 ) & 7;
+	if ((mips_cpu.cputype == CPU_R5432) && (i == 3))
+		i = 4;
+	mips_counter_frequency = bus_frequency*(i+4)/4;
 }
 
 extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
@@ -101,7 +156,7 @@
 	unsigned int count;
 
         /* we are using the cpu counter for timer interrupts */
-	setup_irq(7, irq);
+	setup_irq(CPU_IRQ_BASE + 7, irq);
 
         /* to generate the first timer interrupt */
         count = read_32bit_cp0_register(CP0_COUNT);
@@ -109,24 +164,32 @@
 
 #else
 
-	/* if we don't use Special purpose timer 1 */
-	ddb_out32(SP_TIMER_BASE, SP_TIMER_FREQUENCY/HZ);
+	/* if we use Special purpose timer 1 */
+	ddb_out32(SP_TIMER_BASE, bus_frequency/HZ);
 	ddb_out32(SP_TIMER_BASE+4, 0x1);
 	setup_irq(SP_TIMER_IRQ, irq);
 
 #endif
 }
 
+void __init bus_error_init(void) { /* nothing */ }
+
 static void ddb5477_board_init(void);
 extern void ddb5477_irq_setup(void);
 
 #if defined(CONFIG_BLK_DEV_INITRD)
 extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end;
-#endif 
+#endif
 
 void __init ddb_setup(void)
 {
 	extern int panic_timeout;
+#ifdef CONFIG_BLK_DEV_IDE
+	extern struct ide_ops std_ide_ops;
+#endif
+
+	/* initialize board - we don't trust the loader */
+        ddb5477_board_init();
 
 	irq_setup = ddb5477_irq_setup;
 	set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
@@ -141,17 +204,19 @@
 	/* setup resource limits */
 	ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1;
 	iomem_resource.end = 0xffffffff;
-	
+
 	/* Reboot on panic */
 	panic_timeout = 180;
 
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &std_ide_ops;
+#endif
+
+
 #ifdef CONFIG_FB
 	conswitchp = &dummy_con;
 #endif
 
-	/* initialize board - we don't trust the loader */
-	ddb5477_board_init();
-
 #if defined(CONFIG_BLK_DEV_INITRD)
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 	initrd_start = (unsigned long)&__rd_start;
@@ -161,10 +226,13 @@
 
 static void __init ddb5477_board_init()
 {
+#ifdef CONFIG_PC_KEYB
+	extern struct kbd_ops std_kbd_ops;
+#endif
 	/* ----------- setup PDARs ------------ */
 
 	/* SDRAM should have been set */
-	db_assert(ddb_in32(DDB_SDRAM0) == 
+	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 ? */
@@ -193,11 +261,11 @@
 	}
 
 	/* verify VRC5477 base addr */
-	db_assert(ddb_in32(DDB_VRC5477) == 
+	db_assert(ddb_in32(DDB_VRC5477) ==
 		  ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1));
-	
+
 	/* verify BOOT ROM addr */
-	db_assert(ddb_in32(DDB_BOOTCS) == 
+	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 */
@@ -232,7 +300,7 @@
 	ddb_out32(DDB_BAR51, 0xffffffff);
 	ddb_out32(DDB_BARB1, 0xffffffff);
 
-	/* 
+	/*
 	 * We use pci master register 0  for memory space / config space
 	 * And we use register 1 for IO space.
 	 * Note that for memory space, we bump up the pci base address
@@ -240,22 +308,49 @@
 	 * For PCI IO space, it starts from 0 in PCI IO space but with
 	 * DDB_xx_IO_BASE in CPU physical address space.
 	 */
-	ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE, 
+	ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE,
 		    DDB_PCI_ACCESS_32);
 	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
 
-	ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE, 
+	ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE,
 		    DDB_PCI_ACCESS_32);
-	ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE, 
+	ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE,
                     DDB_PCI_ACCESS_32);
 
-	
+
 	/* PCI cross window should be set properly */
 	ddb_set_pdar(DDB_BARP00, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1);
 	ddb_set_pdar(DDB_BARP10, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1);
 	ddb_set_pdar(DDB_BARP01, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1);
 	ddb_set_pdar(DDB_BARP11, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1);
 
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
+		/* Disable bus diagnostics. */
+		ddb_out32(DDB_PCICTL0_L, 0);
+		ddb_out32(DDB_PCICTL0_H, 0);
+		ddb_out32(DDB_PCICTL1_L, 0);
+		ddb_out32(DDB_PCICTL1_H, 0);
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+		u16			vid;
+		struct pci_bus		bus;
+		struct pci_dev		dev_m1533;
+		extern struct pci_ops 	ddb5477_ext_pci_ops;
+
+		bus.parent      = NULL;    /* we scan the top level only */
+		bus.ops         = &ddb5477_ext_pci_ops;
+		dev_m1533.bus         = &bus;
+		dev_m1533.sysdata     = NULL;
+		dev_m1533.devfn       = 7*8;     // slot 7: M1533 SouthBridge.
+		pci_read_config_word(&dev_m1533, 0, &vid);
+		if (vid == PCI_VENDOR_ID_AL) {
+			printk("Changing mips_machtype to MACH_NEC_ROCKHOPPERII\n");
+			mips_machtype = MACH_NEC_ROCKHOPPERII;
+		}
+	}
+
 	/* enable USB input buffers */
 	ddb_out32(DDB_PIBMISC, 0x00000007);
 
@@ -263,9 +358,83 @@
 	ddb_out32(DDB_GIUFUNSEL, 0x0);
 	// ddb_out32(DDB_GIUFUNSEL, 0xfe0fcfff);  /* NEC recommanded value */
 
-	if (mips_machtype == MACH_NEC_ROCKHOPPER) {
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+#ifdef CONFIG_PC_KEYB
+	printk("kdb_ops is std\n");
+	kbd_ops = &std_kbd_ops;
+#endif
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
+
+		/* enable IDE controller on Ali chip (south bridge) */
+		u8			temp8;
+		struct pci_bus		bus;
+		struct pci_dev		dev_m1533;
+		struct pci_dev		dev_m5229;
+		extern struct pci_ops 	ddb5477_ext_pci_ops;
+
+		/* Setup M1535 registers */
+		bus.parent      = NULL;    /* we scan the top level only */
+		bus.ops         = &ddb5477_ext_pci_ops;
+		dev_m1533.bus         = &bus;
+		dev_m1533.sysdata     = NULL;
+		dev_m1533.devfn       = 7*8;     // slot 7: M1533 SouthBridge.
+
+		/* setup IDE controller
+		 * enable IDE controller (bit 6 - 1)
+		 * IDE IDSEL to be addr:A15 (bit 4:5 - 11)
+		 * disable IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
+		 * enable IDE ATA Primary Bus Signal Pad Control (bit 2 - 1)
+		 */
+		pci_write_config_byte(&dev_m1533, 0x58, 0x74);
+
+		/*
+		 * positive decode (bit6 -0)
+		 * enable IDE controler interrupt (bit 4 -1)
+		 * setup SIRQ to point to IRQ 14 (bit 3:0 - 1101)
+		 */
+		pci_write_config_byte(&dev_m1533, 0x44, 0x1d);
+
+		/* Setup M5229 registers */
+		dev_m5229.bus = &bus;
+		dev_m5229.sysdata = NULL;
+		dev_m5229.devfn = 4*8;  	// slot 4 (AD15): M5229 IDE
+
+		/*
+		 * enable IDE in the M5229 config register 0x50 (bit 0 - 1)
+		 * M5229 IDSEL is addr:15; see above setting
+		 */
+		pci_read_config_byte(&dev_m5229, 0x50, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x50, temp8 | 0x1);
+
+		/*
+		 * enable bus master (bit 2)  and IO decoding  (bit 0)
+		 */
+		pci_read_config_byte(&dev_m5229, 0x04, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x04, temp8 | 0x5);
+
+		/*
+		 * enable native, copied from arch/ppc/k2boot/head.S
+		 * TODO - need volatile, need to be portable
+		 */
+		pci_write_config_byte(&dev_m5229, 0x09, 0xef);
+
+		/* Set Primary Channel Command Block Timing */
+		pci_write_config_byte(&dev_m5229, 0x59, 0x31);
+
+		/*
+		 * Enable primary channel 40-pin cable
+		 * M5229 register 0x4a (bit 0)
+		 */
+		pci_read_config_byte(&dev_m5229, 0x4a, &temp8);
+		pci_write_config_byte(&dev_m5229, 0x4a, temp8 | 0x1);
+	}
+
+	if (mips_machtype == MACH_NEC_ROCKHOPPER
+	   ||  mips_machtype == MACH_NEC_ROCKHOPPERII) {
 		printk("lcd44780: initializing\n");
 		lcd44780_init();
-		lcd44780_puts("Linux/MIPS rolls");
+		lcd44780_puts("MontaVista Linux");
 	}
 }
diff -urN linux-2.4.20-pre6/arch/mips/dec/Makefile linux-2.4.20-pre7/arch/mips/dec/Makefile
--- linux-2.4.20-pre6/arch/mips/dec/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/Makefile	Thu Sep 12 20:01:39 2002
@@ -14,9 +14,10 @@
 
 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
+	time.o
 
 obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
+obj-$(CONFIG_CPU_HAS_WB)	+= wbflush.o
 
 int-handler.o:	int-handler.S
 
diff -urN linux-2.4.20-pre6/arch/mips/dec/int-handler.S linux-2.4.20-pre7/arch/mips/dec/int-handler.S
--- linux-2.4.20-pre6/arch/mips/dec/int-handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/int-handler.S	Thu Sep 12 20:01:39 2002
@@ -240,7 +240,7 @@
 		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.
diff -urN linux-2.4.20-pre6/arch/mips/dec/ioasic-irq.c linux-2.4.20-pre7/arch/mips/dec/ioasic-irq.c
--- linux-2.4.20-pre6/arch/mips/dec/ioasic-irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/ioasic-irq.c	Thu Sep 12 20:01:39 2002
@@ -84,6 +84,7 @@
 	spin_lock(&ioasic_lock);
 	mask_ioasic_irq(irq);
 	spin_unlock(&ioasic_lock);
+	fast_iob();
 }
 
 static inline void end_ioasic_irq(unsigned int irq)
@@ -119,6 +120,7 @@
 static inline void end_ioasic_dma_irq(unsigned int irq)
 {
 	clear_ioasic_irq(irq);
+	fast_iob();
 	end_ioasic_irq(irq);
 }
 
@@ -142,6 +144,7 @@
 
 	/* Mask interrupts. */
 	ioasic_write(SIMR, 0);
+	fast_iob();
 
 	for (i = base; i < base + IO_INR_DMA; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
diff -urN linux-2.4.20-pre6/arch/mips/dec/irq.c linux-2.4.20-pre7/arch/mips/dec/irq.c
--- linux-2.4.20-pre6/arch/mips/dec/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/irq.c	Wed Dec 31 16:00:00 1969
@@ -1,307 +0,0 @@
-/*
- * Code to handle DECstation IRQs plus some generic interrupt stuff.
- *
- * Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1994, 1995, 1996, 1997, 2000 Ralf Baechle
- */
-#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/mipsregs.h>
-#include <asm/system.h>
-
-#include <asm/dec/interrupts.h>
-
-extern void dec_init_kn01(void);
-extern void dec_init_kn230(void);
-extern void dec_init_kn02(void);
-extern void dec_init_kn02ba(void);
-extern void dec_init_kn02ca(void);
-extern void dec_init_kn03(void);
-
-extern asmlinkage void decstation_handle_int(void);
-
-atomic_t irq_err_count;
-
-static inline void mask_irq(unsigned int irq_nr)
-{
-	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);
-}
-
-static inline void unmask_irq(unsigned int irq_nr)
-{
-	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);
-}
-
-void disable_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	mask_irq(irq_nr);
-	restore_flags(flags);
-}
-
-void enable_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-
-	save_and_cli(flags);
-	unmask_irq(irq_nr);
-	restore_flags(flags);
-}
-
-/*
- * 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[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;
-
-	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");
-	}
-	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[cpu][irq]++;
-
-	mask_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();
-		unmask_irq(irq);
-	}
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
-}
-
-/*
- * Idea is to put all interrupts
- * in a single table and differenciate them just by number.
- */
-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 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;
-}
-
-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;
-
-		/* 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;
-}
-
-int probe_irq_off(unsigned long irqs)
-{
-	/* 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);
-}
diff -urN linux-2.4.20-pre6/arch/mips/dec/kn02-irq.c linux-2.4.20-pre7/arch/mips/dec/kn02-irq.c
--- linux-2.4.20-pre6/arch/mips/dec/kn02-irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/kn02-irq.c	Thu Sep 12 20:01:39 2002
@@ -83,6 +83,7 @@
 	spin_lock(&kn02_lock);
 	mask_kn02_irq(irq);
 	spin_unlock(&kn02_lock);
+	iob();
 }
 
 static void end_kn02_irq(unsigned int irq)
@@ -113,6 +114,7 @@
 	/* Mask interrupts and preset write-only bits. */
 	cached_kn02_csr = (*csr & ~0xff0000) | 0xff;
 	*csr = cached_kn02_csr;
+	iob();
 
 	for (i = base; i < base + KN02_IRQ_LINES; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
diff -urN linux-2.4.20-pre6/arch/mips/dec/prom/identify.c linux-2.4.20-pre7/arch/mips/dec/prom/identify.c
--- linux-2.4.20-pre6/arch/mips/dec/prom/identify.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/prom/identify.c	Thu Sep 12 20:01:39 2002
@@ -21,7 +21,7 @@
 
 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",
diff -urN linux-2.4.20-pre6/arch/mips/dec/prom/init.c linux-2.4.20-pre7/arch/mips/dec/prom/init.c
--- linux-2.4.20-pre6/arch/mips/dec/prom/init.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips/dec/prom/init.c	Thu Sep 12 20:01:39 2002
@@ -77,7 +77,7 @@
 		pmax_read = (int (*)(int, void *, int)) PMAX_PROM_READ;
 		pmax_close = (int (*)(int)) PMAX_PROM_CLOSE;
 	}
-} 
+}
 
 int __init prom_init(int argc, char **argv,
 	       unsigned long magic, int *prom_vec)
diff -urN linux-2.4.20-pre6/arch/mips/dec/prom/prom.h linux-2.4.20-pre7/arch/mips/dec/prom/prom.h
--- linux-2.4.20-pre6/arch/mips/dec/prom/prom.h	Fri Jun 25 17:40:12 1999
+++ linux-2.4.20-pre7/arch/mips/dec/prom/prom.h	Thu Sep 12 20:01:39 2002
@@ -1,11 +1,11 @@
-/*  
+/*
  * Miscellaneous definitions used to call the routines contained in the boot
  * PROMs on various models of DECSTATION's.
  * the rights to redistribute these changes.
  */
 
-#ifndef __ASM_DEC_PROM_H 
-#define __ASM_DEC_PROM_H 
+#ifndef __ASM_DEC_PROM_H
+#define __ASM_DEC_PROM_H
 
 /*
  * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's.  Many of
diff -urN linux-2.4.20-pre6/arch/mips/dec/promcon.c linux-2.4.20-pre7/arch/mips/dec/promcon.c
--- linux-2.4.20-pre6/arch/mips/dec/promcon.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/promcon.c	Thu Sep 12 20:01:39 2002
@@ -2,7 +2,7 @@
  * Wrap-around code for a console using the
  * DECstation PROM io-routines.
  *
- * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 1998 Harald Koerfgen
  */
 
 #include <linux/tty.h>
diff -urN linux-2.4.20-pre6/arch/mips/dec/rtc-dec.c linux-2.4.20-pre7/arch/mips/dec/rtc-dec.c
--- linux-2.4.20-pre6/arch/mips/dec/rtc-dec.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips/dec/rtc-dec.c	Thu Sep 12 20:01:39 2002
@@ -3,33 +3,35 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * RTC routines for DECstation style attached Dallas chip.
+ * RTC routines for DECstation style attached Dallas DS1287 chip.
  *
  * Copyright (C) 1998, 2001 by Ralf Baechle
  * Copyright (C) 1998 by Harald Koerfgen
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
+
 #include <linux/mc146818rtc.h>
+#include <linux/types.h>
 
-extern char *dec_rtc_base;
+volatile u8 *dec_rtc_base;
 
 static unsigned char dec_rtc_read_data(unsigned long addr)
 {
-    return (dec_rtc_base[addr * 4]);
+	return dec_rtc_base[addr * 4];
 }
 
 static void dec_rtc_write_data(unsigned char data, unsigned long addr)
 {
-    dec_rtc_base[addr * 4] = data;
+	dec_rtc_base[addr * 4] = data;
 }
 
 static int dec_rtc_bcd_mode(void)
 {
-    return 0;
+	return 0;
 }
 
-struct rtc_ops dec_rtc_ops =
-{
-    &dec_rtc_read_data,
-    &dec_rtc_write_data,
-    &dec_rtc_bcd_mode
+struct rtc_ops dec_rtc_ops = {
+	&dec_rtc_read_data,
+	&dec_rtc_write_data,
+	&dec_rtc_bcd_mode
 };
diff -urN linux-2.4.20-pre6/arch/mips/dec/setup.c linux-2.4.20-pre7/arch/mips/dec/setup.c
--- linux-2.4.20-pre6/arch/mips/dec/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/setup.c	Thu Sep 12 20:01:39 2002
@@ -25,6 +25,7 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 #include <asm/traps.h>
+#include <asm/wbflush.h>
 
 #include <asm/dec/interrupts.h>
 #include <asm/dec/kn01.h>
@@ -45,10 +46,8 @@
 
 extern asmlinkage void decstation_handle_int(void);
 
-
-char *dec_rtc_base = (void *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */
-
 volatile u32 *ioasic_base;
+unsigned long dec_kn_slot_size;
 
 /*
  * IRQ routing and priority tables.  Priorites are set as follows:
@@ -71,7 +70,7 @@
  *
  * * -- shared with SCSI
  */
- 
+
 int dec_interrupt[DEC_NR_INTS] = {
 	[0 ... DEC_NR_INTS - 1] = -1
 };
@@ -89,10 +88,6 @@
 static struct irqaction haltirq = {dec_intr_halt, 0, 0, "halt", NULL, NULL};
 
 
-extern void wbflush_setup(void);
-
-extern struct rtc_ops dec_rtc_ops;
-
 void (*board_time_init) (struct irqaction * irq);
 
 
@@ -208,7 +203,8 @@
 void __init dec_init_kn01(void)
 {
 	/* Setup some memory addresses. */
-	dec_rtc_base = (char *) KN01_RTC_BASE;
+	dec_rtc_base = (void *)KN01_RTC_BASE;
+	dec_kn_slot_size = KN01_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn01_interrupt,
@@ -286,7 +282,8 @@
 void __init dec_init_kn230(void)
 {
 	/* Setup some memory addresses. */
-	dec_rtc_base = (char *) KN01_RTC_BASE;
+	dec_rtc_base = (void *)KN01_RTC_BASE;
+	dec_kn_slot_size = KN01_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn230_interrupt,
@@ -379,7 +376,8 @@
 void __init dec_init_kn02(void)
 {
 	/* Setup some memory addresses. */
-	dec_rtc_base = (char *) KN02_RTC_BASE;
+	dec_rtc_base = (void *)KN02_RTC_BASE;
+	dec_kn_slot_size = KN02_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn02_interrupt,
@@ -426,7 +424,7 @@
 	[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_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,
@@ -483,8 +481,9 @@
 void __init dec_init_kn02ba(void)
 {
 	/* Setup some memory addresses. */
-	ioasic_base = (void *) KN02BA_IOASIC_BASE;
-	dec_rtc_base = (char *) KN02BA_RTC_BASE;
+	ioasic_base = (void *)KN02BA_IOASIC_BASE;
+	dec_rtc_base = (void *)KN02BA_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn02ba_interrupt,
@@ -584,8 +583,9 @@
 void __init dec_init_kn02ca(void)
 {
 	/* Setup some memory addresses. */
-	ioasic_base = (void *) KN02CA_IOASIC_BASE;
-	dec_rtc_base = (char *) KN02CA_RTC_BASE;
+	ioasic_base = (void *)KN02CA_IOASIC_BASE;
+	dec_rtc_base = (void *)KN02CA_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn02ca_interrupt,
@@ -659,9 +659,9 @@
 		{ 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) }, 
+	{ { i: DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) },
 		{ p: kn03_io_int } },
-	{ { i: DEC_CPU_IRQ_ALL }, 
+	{ { i: DEC_CPU_IRQ_ALL },
 		{ p: cpu_all_int } },
 };
 
@@ -689,12 +689,13 @@
 void __init dec_init_kn03(void)
 {
 	/* Setup some memory addresses.  */
-	ioasic_base = (void *) KN03_IOASIC_BASE;
-	dec_rtc_base = (char *) KN03_RTC_BASE;
+	ioasic_base = (void *)KN03_IOASIC_BASE;
+	dec_rtc_base = (void *)KN03_RTC_BASE;
+	dec_kn_slot_size = IOASIC_SLOT_SIZE;
 
 	/* IRQ routing. */
 	memcpy(&dec_interrupt, &kn03_interrupt,
-		sizeof(kn03_interrupt));	
+		sizeof(kn03_interrupt));
 
 	/* CPU IRQ priorities. */
 	memcpy(&cpu_mask_nr_tbl, &kn03_cpu_mask_nr_tbl,
@@ -760,4 +761,7 @@
 		setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
 }
 
+EXPORT_SYMBOL(ioasic_base);
+EXPORT_SYMBOL(dec_rtc_base);
+EXPORT_SYMBOL(dec_kn_slot_size);
 EXPORT_SYMBOL(dec_interrupt);
diff -urN linux-2.4.20-pre6/arch/mips/dec/time.c linux-2.4.20-pre7/arch/mips/dec/time.c
--- linux-2.4.20-pre6/arch/mips/dec/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/dec/time.c	Thu Sep 12 20:01:39 2002
@@ -110,7 +110,7 @@
 		: "r" (count), "r" (quotient));
 
 	/*
-	 * Due to possible jiffies inconsistencies, we need to check 
+	 * 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)
@@ -160,9 +160,9 @@
 	return res;
 }
 
-/* This function must be called with interrupts disabled 
+/* This function must be called with interrupts disabled
  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
- * 
+ *
  * However, the pc-audio speaker driver changes the divisor so that
  * it gets interrupted rather more often - it loads 64 into the
  * counter rather than 11932! This has an adverse impact on
@@ -176,7 +176,7 @@
  * using either the RTC or the 8253 timer. The decision would be
  * based on whether there was any other device around that needed
  * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
- * and then do some jiggery to have a version of do_timer that 
+ * and then do some jiggery to have a version of do_timer that
  * advanced the clock by 1/1024 s. Every time that reached over 1/100
  * of a second, then do all the old code. If the time was kept correct
  * then do_gettimeoffset could just return 0 - there is no low order
@@ -187,7 +187,7 @@
  * often than every 120 us or so.
  *
  * Anyway, this needs more thought....          pjsg (1993-08-28)
- * 
+ *
  * If you are really that interested, you should be reading
  * comp.protocols.time.ntp!
  */
diff -urN linux-2.4.20-pre6/arch/mips/dec/wbflush.c linux-2.4.20-pre7/arch/mips/dec/wbflush.c
--- linux-2.4.20-pre6/arch/mips/dec/wbflush.c	Thu Sep 12 20:01:30 2002
+++ linux-2.4.20-pre7/arch/mips/dec/wbflush.c	Thu Sep 12 20:01:39 2002
@@ -11,15 +11,18 @@
  * for more details.
  *
  * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
  */
 
-#include <asm/bootinfo.h>
 #include <linux/init.h>
 
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+#include <asm/wbflush.h>
+
 static void wbflush_kn01(void);
 static void wbflush_kn210(void);
-static void wbflush_kn02ba(void);
-static void wbflush_kn03(void);
+static void wbflush_mips(void);
 
 void (*__wbflush) (void);
 
@@ -27,28 +30,23 @@
 {
 	switch (mips_machtype) {
 	case MACH_DS23100:
-	    __wbflush = wbflush_kn01;
-	    break;
-	case MACH_DS5100:	/*  DS5100 MIPSMATE */
-	    __wbflush = wbflush_kn210;
-	    break;
 	case MACH_DS5000_200:	/* DS5000 3max */
-	    __wbflush = wbflush_kn01;
-	    break;
+		__wbflush = wbflush_kn01;
+		break;
+	case MACH_DS5100:	/* DS5100 MIPSMATE */
+		__wbflush = wbflush_kn210;
+		break;
 	case MACH_DS5000_1XX:	/* DS5000/100 3min */
-	    __wbflush = wbflush_kn02ba;
-	    break;
-	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
-	    __wbflush = wbflush_kn03;
-	    break;
 	case MACH_DS5000_XX:	/* Personal DS5000/2x */
-	    __wbflush = wbflush_kn02ba;
-	    break;
+	case MACH_DS5000_2X0:	/* DS5000/240 3max+ */
+	default:
+		__wbflush = wbflush_mips;
+		break;
 	}
 }
 
 /*
- * For the DS3100 and DS5000/200 the writeback buffer functions
+ * For the DS3100 and DS5000/200 the R2020/R3220 writeback buffer functions
  * as part of Coprocessor 0.
  */
 static void wbflush_kn01(void)
@@ -78,29 +76,16 @@
 	"mtc0\t$2,$12\n\t"
 	"nop\n\t"
 	".set\tpop"
-  : : :"$2", "$3");
-}
-
-/*
- * Looks like some magic with the System Interrupt Mask Register
- * in the famous IOASIC for kmins and maxines.
- */
-static void wbflush_kn02ba(void)
-{
-    asm(".set\tpush\n\t"
-	".set\tnoreorder\n\t"
-	"lui\t$2,0xbc04\n\t"
-	"lw\t$3,0x120($2)\n\t"
-	"lw\t$3,0x120($2)\n\t"
-	".set\tpop"
-  : : :"$2", "$3");
+	: : : "$2", "$3");
 }
 
 /*
- * The DS500/2x0 doesn't need to write back the WB.
+ * I/O ASIC systems use a standard writeback buffer that gets flushed
+ * upon an uncached read.
  */
-static void wbflush_kn03(void)
+static void wbflush_mips(void)
 {
+	__fast_iob();
 }
 
 #include <linux/module.h>
diff -urN linux-2.4.20-pre6/arch/mips/defconfig linux-2.4.20-pre7/arch/mips/defconfig
--- linux-2.4.20-pre6/arch/mips/defconfig	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,53 +36,68 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_MEMORY=y
 CONFIG_BOARD_SCACHE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_SWAP_IO_SPACE=y
 CONFIG_IRQ_CPU=y
-CONFIG_PC_KEYB=y
-CONFIG_SGI=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+CONFIG_SGI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -88,7 +105,8 @@
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
-# CONFIG_ARC_CONSOLE is not set
+CONFIG_ARC_CONSOLE=y
+# CONFIG_IP22_EISA is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -106,6 +124,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -140,6 +160,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -219,6 +240,13 @@
 # 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
@@ -321,6 +349,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -367,6 +396,15 @@
 # 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
@@ -419,7 +457,6 @@
 # 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
@@ -430,6 +467,7 @@
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 CONFIG_INDYDOG=y
+# CONFIG_AMD7XX_TCO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -444,11 +482,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # SGI Character devices
 #
 CONFIG_SGI_NEWPORT_CONSOLE=y
@@ -468,6 +501,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -485,6 +520,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -515,6 +553,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -528,7 +567,6 @@
 # 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
@@ -548,10 +586,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -586,18 +630,15 @@
 # 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
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-atlas linux-2.4.20-pre7/arch/mips/defconfig-atlas
--- linux-2.4.20-pre6/arch/mips/defconfig-atlas	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-atlas	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -19,6 +20,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -32,20 +34,28 @@
 CONFIG_MIPS_ATLAS=y
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM 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_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
@@ -56,32 +66,36 @@
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # 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_R5000 is not set
 # CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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_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=y
+# CONFIG_CPU_HAS_LLDSCD is not set
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_BINFMT_IRIX=y
+# CONFIG_BINFMT_IRIX is not set
 # CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
@@ -95,11 +109,13 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -130,11 +146,12 @@
 # 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_LOOP=y
 # 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
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -151,13 +168,14 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
@@ -165,6 +183,7 @@
 # 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
@@ -273,8 +292,14 @@
 # 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_NCR53C8XX=y
 # CONFIG_SCSI_SYM53C8XX is not set
+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_SYMBIOS_COMPAT is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -330,7 +355,38 @@
 # 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_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 is not set
+# CONFIG_E100 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_OLD_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_TC35815 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=y
 # CONFIG_NET_POCKET is not set
 
 #
@@ -338,6 +394,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -384,6 +441,15 @@
 # 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
@@ -424,7 +490,7 @@
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_NVRAM is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -437,15 +503,10 @@
 # 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_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
@@ -454,6 +515,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -462,7 +525,7 @@
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
-CONFIG_EFS_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
@@ -471,6 +534,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -497,12 +563,14 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP 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
@@ -514,17 +582,35 @@
 # 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_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_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -540,15 +626,6 @@
 # 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
@@ -557,3 +634,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-capcella linux-2.4.20-pre7/arch/mips/defconfig-capcella
--- linux-2.4.20-pre6/arch/mips/defconfig-capcella	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/defconfig-capcella	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,645 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# 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_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+CONFIG_ZAO_CAPCELLA=y
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_CPU_VR41XX=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_TIME_C=y
+CONFIG_VR41XX_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_ISA is not set
+CONFIG_PCI=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
+CONFIG_DUMMY_KEYB=y
+# CONFIG_SCSI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 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
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# 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
+# CONFIG_BLK_STATS 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=y
+# 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=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
+# 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 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_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_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 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_OLD_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_TC35815 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_E1000 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
+
+#
+# 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 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=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_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 is not set
+# CONFIG_AMD7XX_TCO 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
+
+#
+# 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_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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS 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_NFSD_TCP 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
+
+#
+# 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_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV 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
+
+#
+# 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-cobalt linux-2.4.20-pre7/arch/mips/defconfig-cobalt
--- linux-2.4.20-pre6/arch/mips/defconfig-cobalt	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-cobalt	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -19,6 +20,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -32,21 +34,28 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA 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_I8259=y
 CONFIG_PCI=y
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
@@ -56,25 +65,28 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 CONFIG_CPU_NEVADA=y
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=y
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -97,6 +109,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -131,6 +145,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -271,6 +286,8 @@
 # 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
@@ -341,13 +358,13 @@
 # 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_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -359,11 +376,12 @@
 # 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -375,6 +393,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -421,6 +440,15 @@
 # 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
@@ -474,11 +502,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -491,6 +514,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -508,6 +533,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -538,6 +566,7 @@
 # CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -551,7 +580,6 @@
 # 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
@@ -571,10 +599,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -590,15 +624,6 @@
 # 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
@@ -607,3 +632,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-ddb5476 linux-2.4.20-pre7/arch/mips/defconfig-ddb5476
--- linux-2.4.20-pre6/arch/mips/defconfig-ddb5476	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-ddb5476	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -10,39 +11,49 @@
 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_PB1100 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_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_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
 CONFIG_DDB5476=y
 # CONFIG_DDB5477 is not set
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC 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_ZAO_CAPCELLA 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=y
 CONFIG_PCI=y
 CONFIG_PC_KEYB=y
@@ -54,59 +65,57 @@
 CONFIG_PCI_AUTO=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_EISA=y
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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
+CONFIG_CPU_HAS_SYNC=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_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=y
 # 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_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -119,6 +128,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
@@ -126,11 +141,14 @@
 # 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
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -175,6 +193,11 @@
 #
 # 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
@@ -192,6 +215,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -215,6 +243,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
@@ -229,6 +258,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
@@ -240,12 +270,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_IDEDMA_PCI is not set
-# CONFIG_BLK_DEV_ADMA is not set
 # 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 is not set
 # 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 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
@@ -253,11 +286,14 @@
 # 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_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
@@ -330,13 +366,13 @@
 # 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=y
+# CONFIG_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -348,11 +384,12 @@
 # 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -364,11 +401,13 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 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
@@ -414,6 +453,15 @@
 # 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
@@ -438,6 +486,7 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -457,7 +506,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
@@ -472,11 +520,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -489,6 +532,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -502,10 +547,13 @@
 # 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -536,6 +584,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -549,7 +598,6 @@
 # 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
@@ -560,6 +608,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -573,15 +626,18 @@
 # 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=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -603,116 +659,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
-
-#
-#   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
+# Bluetooth support
 #
-
-#
-# 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
+# CONFIG_BLUEZ is not set
 
 #
 # Kernel hacking
@@ -723,3 +672,9 @@
 CONFIG_DEBUG=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-ddb5477 linux-2.4.20-pre7/arch/mips/defconfig-ddb5477
--- linux-2.4.20-pre6/arch/mips/defconfig-ddb5477	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-ddb5477	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -10,39 +11,50 @@
 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_PB1100 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_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_SIBYTE_SB1250 is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 CONFIG_DDB5477=y
+CONFIG_DDB5477_BUS_FREQUENCY=0
 # CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC 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_ZAO_CAPCELLA 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_PCI=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NEW_IRQ=y
@@ -51,54 +63,59 @@
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI_AUTO=y
 CONFIG_DUMMY_KEYB=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
+CONFIG_I8259=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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
+CONFIG_CPU_HAS_SYNC=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_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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -111,6 +128,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
@@ -118,11 +141,14 @@
 # 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
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -167,6 +193,11 @@
 #
 # 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
@@ -184,6 +215,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Telephony Support
 #
 # CONFIG_PHONE is not set
@@ -243,18 +279,18 @@
 # CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
+CONFIG_PCNET32=y
 # 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_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -266,11 +302,12 @@
 # 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -282,11 +319,13 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 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
@@ -327,9 +366,13 @@
 # CONFIG_ISDN is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
+# Input core support
 #
-# CONFIG_CD_NO_IDESCSI is not set
+# 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
@@ -371,7 +414,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
@@ -386,11 +428,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -403,6 +440,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -416,10 +455,13 @@
 # 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -450,6 +492,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -463,7 +506,6 @@
 # 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
@@ -474,9 +516,15 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
@@ -488,10 +536,10 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE 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
@@ -507,116 +555,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
-
-#
-#   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
+# Bluetooth support
 #
-# 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
+# CONFIG_BLUEZ is not set
 
 #
 # Kernel hacking
@@ -627,3 +568,9 @@
 CONFIG_DEBUG=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-decstation linux-2.4.20-pre7/arch/mips/defconfig-decstation
--- linux-2.4.20-pre6/arch/mips/defconfig-decstation	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-decstation	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,17 +36,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -56,25 +64,27 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 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
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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=y
+# CONFIG_CPU_HAS_SYNC is not set
 
 #
 # General setup
@@ -97,6 +107,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -131,6 +143,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -209,6 +222,13 @@
 # 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
@@ -310,6 +330,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -356,6 +377,15 @@
 # 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
@@ -409,11 +439,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # DECStation Character devices
 #
 CONFIG_SERIAL=y
@@ -435,6 +460,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -452,6 +479,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -482,6 +512,7 @@
 # CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 # CONFIG_SUNRPC is not set
 # CONFIG_LOCKD is not set
 # CONFIG_SMB_FS is not set
@@ -495,7 +526,6 @@
 # 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
@@ -515,10 +545,16 @@
 # CONFIG_SGI_PARTITION is not set
 CONFIG_ULTRIX_PARTITION=y
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -534,15 +570,6 @@
 # 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
@@ -551,3 +578,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-eagle linux-2.4.20-pre7/arch/mips/defconfig-eagle
--- linux-2.4.20-pre6/arch/mips/defconfig-eagle	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/defconfig-eagle	Thu Sep 12 20:01:39 2002
@@ -0,0 +1,677 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# 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_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE=y
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_CPU_VR41XX=y
+CONFIG_NEW_IRQ=y
+CONFIG_IRQ_CPU=y
+CONFIG_NEW_TIME_C=y
+CONFIG_VR41XX_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_ISA is not set
+CONFIG_PCI=y
+CONFIG_NEW_PCI=y
+CONFIG_PCI_AUTO=y
+CONFIG_DUMMY_KEYB=y
+# CONFIG_SCSI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 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
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# 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 is not set
+# 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=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 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=y
+CONFIG_MTD_PHYSMAP_START=1c000000
+CONFIG_MTD_PHYSMAP_LEN=2000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS 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=y
+# 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=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
+# 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=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 is not set
+# CONFIG_E100 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_OLD_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_TC35815 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_E1000 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
+
+#
+# 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 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=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_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_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_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 is not set
+# CONFIG_AMD7XX_TCO 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
+
+#
+# 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_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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG 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=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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS 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_NFSD_TCP 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
+
+#
+# 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_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV 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
+
+#
+# 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
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-ev64120 linux-2.4.20-pre7/arch/mips/defconfig-ev64120
--- linux-2.4.20-pre6/arch/mips/defconfig-ev64120	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-ev64120	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -38,17 +40,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -62,26 +70,29 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -106,6 +117,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -140,6 +153,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -274,11 +288,11 @@
 # 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_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -290,11 +304,12 @@
 # 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -306,6 +321,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -359,6 +375,15 @@
 # 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
@@ -412,11 +437,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -429,6 +449,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -446,6 +468,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -476,6 +501,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -489,7 +515,6 @@
 # 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
@@ -500,6 +525,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -515,15 +545,6 @@
 # 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
@@ -532,3 +553,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-ev96100 linux-2.4.20-pre7/arch/mips/defconfig-ev96100
--- linux-2.4.20-pre6/arch/mips/defconfig-ev96100	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-ev96100	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,17 +36,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -60,27 +68,29 @@
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
 # 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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -105,6 +115,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -139,6 +151,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -274,13 +287,13 @@
 # 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_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -292,11 +305,12 @@
 # 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -308,6 +322,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -354,6 +369,15 @@
 # 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
@@ -407,11 +431,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -424,6 +443,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -441,6 +462,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -471,6 +495,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -484,7 +509,6 @@
 # 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
@@ -495,6 +519,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -510,15 +539,6 @@
 # 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
@@ -527,3 +547,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-ip22 linux-2.4.20-pre7/arch/mips/defconfig-ip22
--- linux-2.4.20-pre6/arch/mips/defconfig-ip22	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-ip22	Thu Sep 12 20:01:39 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,53 +36,68 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_MEMORY=y
 CONFIG_BOARD_SCACHE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_SWAP_IO_SPACE=y
 CONFIG_IRQ_CPU=y
-CONFIG_PC_KEYB=y
-CONFIG_SGI=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+CONFIG_SGI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_BOARD_SCACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -88,7 +105,8 @@
 # CONFIG_CPU_LITTLE_ENDIAN is not set
 CONFIG_BINFMT_IRIX=y
 CONFIG_FORWARD_KEYBOARD=y
-# CONFIG_ARC_CONSOLE is not set
+CONFIG_ARC_CONSOLE=y
+# CONFIG_IP22_EISA is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -106,6 +124,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -140,6 +160,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -219,6 +240,13 @@
 # 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
@@ -321,6 +349,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -367,6 +396,15 @@
 # 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
@@ -419,7 +457,6 @@
 # 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
@@ -430,6 +467,7 @@
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 CONFIG_INDYDOG=y
+# CONFIG_AMD7XX_TCO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -444,11 +482,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # SGI Character devices
 #
 CONFIG_SGI_NEWPORT_CONSOLE=y
@@ -468,6 +501,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -485,6 +520,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -515,6 +553,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -528,7 +567,6 @@
 # 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
@@ -548,10 +586,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -586,18 +630,15 @@
 # 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
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-malta linux-2.4.20-pre7/arch/mips/defconfig-malta
--- linux-2.4.20-pre6/arch/mips/defconfig-malta	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-malta	Thu Sep 12 20:01:40 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -19,6 +20,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -32,48 +34,57 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 CONFIG_MIPS_MALTA=y
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_I8259=y
-CONFIG_PCI=y
+CONFIG_BOOT_ELF32=y
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+CONFIG_I8259=y
+CONFIG_L1_CACHE_SHIFT=5
 CONFIG_NEW_IRQ=y
 CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_PC_KEYB=y
+CONFIG_PCI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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
@@ -81,6 +92,7 @@
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
 # CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -98,11 +110,13 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -138,6 +152,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -339,11 +354,11 @@
 # 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_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -355,11 +370,12 @@
 # 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -371,6 +387,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -417,6 +434,15 @@
 # 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
@@ -470,11 +496,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -487,6 +508,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -504,6 +527,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -534,6 +560,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -547,7 +574,6 @@
 # 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
@@ -558,6 +584,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -573,15 +604,6 @@
 # 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
@@ -590,3 +612,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-pb1000 linux-2.4.20-pre7/arch/mips/defconfig-pb1000
--- linux-2.4.20-pre6/arch/mips/defconfig-pb1000	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-pb1000	Thu Sep 12 20:01:40 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -22,6 +23,7 @@
 # CONFIG_ACER_PICA_61 is not set
 CONFIG_MIPS_PB1000=y
 CONFIG_PCI_AUTO=y
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -35,17 +37,23 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -55,33 +63,36 @@
 CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
-MAX_HWIFS=1
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_AU1000_USB_DEVICE=y
 
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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_64BIT_PHYS_ADDR=y
 CONFIG_CPU_ADVANCED=y
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
 CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -105,6 +116,7 @@
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1000=m
+CONFIG_PCMCIA_PB1X00=y
 
 #
 # PCI Hotplug Support
@@ -120,6 +132,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -163,6 +177,7 @@
 # CONFIG_MTD_PHYSMAP is not set
 CONFIG_MTD_PB1000=y
 # CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
 # CONFIG_MTD_PCI is not set
@@ -211,10 +226,11 @@
 # 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_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
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -396,6 +412,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -429,7 +446,18 @@
 #
 # PCMCIA network device support
 #
-# CONFIG_NET_PCMCIA is not set
+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
@@ -439,7 +467,49 @@
 #
 # IrDA (infrared) support
 #
-# CONFIG_IRDA is not set
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA 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
+#
+
+#
+# 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_AU1000_FIR=m
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
 
 #
 # ISDN subsystem
@@ -447,9 +517,19 @@
 # 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_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 CONFIG_SERIAL_NONSTANDARD=y
@@ -463,6 +543,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -473,6 +554,8 @@
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
 CONFIG_AU1000_UART=y
 CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_AU1000_USB_TTY is not set
+# CONFIG_AU1000_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -523,15 +606,11 @@
 # PCMCIA character devices
 #
 # CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
 CONFIG_AU1000_GPIO=y
 # CONFIG_TS_AU1000_ADS7846 is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -544,6 +623,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -562,6 +643,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -592,6 +676,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -605,7 +690,6 @@
 # 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
@@ -616,9 +700,67 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV 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_E1356=y
+CONFIG_PB1000_CRT=y
+# CONFIG_PB1000_NTSC is not set
+# CONFIG_PB1000_TFT 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_ALI5455 is not set
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
@@ -630,6 +772,7 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
@@ -653,15 +796,6 @@
 # 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
@@ -670,3 +804,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-pb1100 linux-2.4.20-pre7/arch/mips/defconfig-pb1100
--- linux-2.4.20-pre6/arch/mips/defconfig-pb1100	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/defconfig-pb1100	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,874 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# 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_PB1100=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_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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA 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 is not set
+CONFIG_NEW_PCI=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_AU1000_USB_DEVICE=y
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_CPU_ADVANCED=y
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=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=m
+CONFIG_PCMCIA_PB1X00=y
+
+#
+# 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# 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 is not set
+# CONFIG_MTD_PB1100 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
+# CONFIG_BLK_STATS 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 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
+#
+# 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 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA 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
+#
+
+#
+# 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_AU1000_FIR=y
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR 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=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_SYNCLINKMP 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_AU1000_USB_TTY is not set
+# CONFIG_AU1000_USB_RAW is not set
+# 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
+
+#
+# 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
+
+#
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_AU1000_GPIO is not set
+# CONFIG_TS_AU1000_ADS7846 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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS 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_NFSD_TCP 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
+
+#
+# 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
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV 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_E1356 is not set
+# CONFIG_FB_AU1100 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_ALI5455 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_FORTE 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 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-pb1500 linux-2.4.20-pre7/arch/mips/defconfig-pb1500
--- linux-2.4.20-pre6/arch/mips/defconfig-pb1500	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-pb1500	Thu Sep 12 20:01:40 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 CONFIG_MIPS_PB1500=y
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,46 +36,54 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE 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_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA 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_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
+CONFIG_AU1000_USB_DEVICE=y
 
 #
 # CPU selection
 #
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 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
@@ -81,6 +91,7 @@
 CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_LLDSCD is not set
 CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -119,6 +130,8 @@
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -162,6 +175,7 @@
 # CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_PB1000 is not set
 CONFIG_MTD_PB1500=y
+# CONFIG_MTD_PB1100 is not set
 CONFIG_MTD_PB1500_BOOT=y
 # CONFIG_MTD_PB1500_USER is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
@@ -216,6 +230,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -371,6 +386,8 @@
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 CONFIG_BLK_DEV_HPT366=y
+# 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
@@ -442,11 +459,11 @@
 # 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_E100 is not set
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -458,11 +475,12 @@
 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_8139_OLD_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_TC35815 is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
@@ -474,6 +492,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -543,6 +562,17 @@
 # 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=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -560,6 +590,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -570,6 +601,8 @@
 # CONFIG_SERIAL_TX3912_CONSOLE is not set
 CONFIG_AU1000_UART=y
 CONFIG_AU1000_SERIAL_CONSOLE=y
+# CONFIG_AU1000_USB_TTY is not set
+# CONFIG_AU1000_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -642,15 +675,11 @@
 # PCMCIA character devices
 #
 # CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_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
@@ -663,6 +692,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
@@ -683,6 +714,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -713,6 +747,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_SMB_FS=m
@@ -727,7 +762,6 @@
 # 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
@@ -780,6 +814,11 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -804,6 +843,7 @@
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_FBCON_ADVANCED=y
 # CONFIG_FBCON_MFB is not set
@@ -831,6 +871,7 @@
 # Sound
 #
 CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
 # CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
@@ -842,6 +883,7 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
@@ -881,6 +923,7 @@
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
 
 #
 #   SCSI support is needed for USB Storage
@@ -893,6 +936,7 @@
 # CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_HP8200e is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
@@ -903,6 +947,7 @@
 CONFIG_USB_HID=y
 # CONFIG_USB_HIDINPUT is not set
 # CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
 
 #
@@ -941,39 +986,15 @@
 # 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_TIGL is not set
 # CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
 
 #
 # Bluetooth support
@@ -981,17 +1002,6 @@
 # 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
@@ -1000,3 +1010,9 @@
 # CONFIG_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-sb1250-swarm linux-2.4.20-pre7/arch/mips/defconfig-sb1250-swarm
--- linux-2.4.20-pre6/arch/mips/defconfig-sb1250-swarm	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/defconfig-sb1250-swarm	Thu Sep 12 20:01:40 2002
@@ -3,6 +3,7 @@
 #
 CONFIG_MIPS=y
 CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
 
 #
 # Code maturity level options
@@ -21,6 +22,7 @@
 #
 # CONFIG_ACER_PICA_61 is not set
 # CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_ALGOR_P4032 is not set
 # CONFIG_BAGET_MIPS is not set
@@ -34,26 +36,32 @@
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
 # CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
 # CONFIG_OLIVETTI_M700 is not set
 # CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
 CONFIG_SIBYTE_SB1250=y
-# CONFIG_PCI is not set
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE 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_PCI is not set
+CONFIG_SIBYTE_SWARM=y
 # CONFIG_SNI_RM200_PCI is not set
 # CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
@@ -61,35 +69,43 @@
 CONFIG_NEW_TIME_C=y
 CONFIG_DUMMY_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
 # 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 CONFIG_CPU_SB1=y
-# CONFIG_CPU_MIPS32 is not set
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_SB1_PASS_1=y
+# CONFIG_CPU_SB1_PASS_2 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_SB1_CACHE_ERROR=y
+CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y
+# CONFIG_SB1_CERR_SPIN is not set
 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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -109,11 +125,13 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 
@@ -148,6 +166,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -222,6 +241,13 @@
 # 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
@@ -246,7 +272,6 @@
 #
 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
@@ -264,6 +289,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -310,6 +336,15 @@
 # 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
@@ -326,6 +361,7 @@
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -334,7 +370,6 @@
 # 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
@@ -387,11 +422,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -404,6 +434,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
@@ -421,6 +453,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -451,6 +486,7 @@
 # CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -465,7 +501,6 @@
 # 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
@@ -476,6 +511,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -491,17 +531,14 @@
 # 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/defconfig-sead linux-2.4.20-pre7/arch/mips/defconfig-sead
--- linux-2.4.20-pre6/arch/mips/defconfig-sead	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/defconfig-sead	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,363 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# 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_PB1100 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_MIPS_SEAD=y
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_PCI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 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
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_NET is not set
+# 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 is not set
+# 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_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
+# 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=y
+CONFIG_BLK_DEV_RAM_SIZE=18432
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# MIPS initrd options
+#
+CONFIG_EMBEDDED_RAMDISK=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
+
+#
+# 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO 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=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD 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
+
+#
+# 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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS 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
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_ZISOFS_FS 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_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/cntmr.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/cntmr.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/cntmr.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/cntmr.c	Thu Sep 12 20:01:40 2002
@@ -25,7 +25,7 @@
 * 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. 
+*          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.
@@ -63,11 +63,11 @@
 }
 
 /********************************************************************
-* cntTmrDisable - Disables the timer/counter operation and return its 
+* 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 
+* RETURNS: The counter/timer value (unsigned int), if any of the arguments are
 *          erroneous return 0.
 *********************************************************************/
 
@@ -166,10 +166,10 @@
 *                 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. 
+*                 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 .
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/Makefile linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/Makefile
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/Makefile	Thu Sep 12 20:01:40 2002
@@ -11,13 +11,13 @@
 #
 #   The system comes in three forms:
 #
-#       1. - ramsys - 
+#       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 - 
+#       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
@@ -26,10 +26,10 @@
 #          Note: burner.srec is the utility that will allow
 #          the user to get this image into flash.
 #
-#       3. - flashsys2 - 
+#       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 
+#          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.
@@ -75,7 +75,7 @@
 	gcc -o doit doit.c
 
 piggy.gz: $(SYSTEM)
-	rm -f piggy piggy.gz 
+	rm -f piggy piggy.gz
 	$(OBJCOPY) -S -O binary $(SYSTEM) piggy
 	gzip -f -9 < piggy > piggy.gz
 
@@ -89,7 +89,7 @@
 
 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) 
+	$(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)/.
@@ -97,7 +97,7 @@
 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 
+	@# 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
@@ -105,8 +105,8 @@
 	@# 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) 
+	@#
+	$(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.
@@ -125,7 +125,7 @@
 	@# 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) 
+	@# 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)/.
@@ -139,8 +139,8 @@
 	@# 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) 
+	@#
+	$(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.
@@ -168,7 +168,7 @@
 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) 
+	$(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)/.
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/README linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/README
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/README	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/README	Thu Sep 12 20:01:40 2002
@@ -21,13 +21,13 @@
   Four systems are availalbe for download to the EVB64120A
   board.
 
-   1. - ramsys - 
+   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 - 
+   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
@@ -36,10 +36,10 @@
       Note: burner.srec is the utility that will allow
       the user to get this image into flash.
 
-   3. - flashsys2 - 
+   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 
+      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.
@@ -53,8 +53,8 @@
 ==========================
 
   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 
+  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`
@@ -69,7 +69,7 @@
 ========================================
 
   In this scenario vmlinux runs out of flash code
-  automatically on every power up. This means that 
+  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
@@ -77,7 +77,7 @@
      are found when booting PMON.
 
      Jumper settings. J11 - Removed
-                      J20 - Moved from the 1&2 position to 
+                      J20 - Moved from the 1&2 position to
                             the 2&3 position instead
 
   2. Use PMON to "load" the burner.srec image and then
@@ -89,12 +89,12 @@
      utility. The utililty will indicate when the burn
      process has completed.
 
-  4. Now switch off power and change the jumpers to 
+  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 
+                      J20 - Moved from the 2&3 position to
                             the 1&2 position instead
 
 Example: Running from flash: Scenario #2
@@ -111,7 +111,7 @@
      are found when booting PMON.
 
      Jumper settings. J11 - Removed
-                      J20 - Moved from the 1&2 position to 
+                      J20 - Moved from the 1&2 position to
                             the 2&3 position instead
 
   2. Use PMON to "load" the burner.srec image and then
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/burner.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/burner.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/burner.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/burner.c	Thu Sep 12 20:01:40 2002
@@ -3,7 +3,7 @@
  *
  *  By RidgeRun Inc (Leveraged from Galileo's main.c, misc.c, etc).
  *
- *  Burn image from ram to flash 
+ *  Burn image from ram to flash
  *  For use with Galileo EVB64120A MIPS eval board.
  */
 #include <asm/types.h>
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/doit.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/doit.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/doit.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/doit.c	Thu Sep 12 20:01:40 2002
@@ -12,7 +12,7 @@
  *
  *    Example Usage:
  *       ./doit < piggy.gz > piggy.S
- *       
+ *
  */
 
 #include <stdio.h>
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c	Thu Sep 12 20:01:40 2002
@@ -29,14 +29,14 @@
 
 /******************************************************************************
 * Those two tables contain the supported flash devices information needed by
-* the driver: 
-* The first table "flashParametrs" starts with 10 shared fields 
+* 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 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: 
+* 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).
@@ -120,14 +120,14 @@
 };
 
 /********************************************************************
-* flashInit - Initializes the FLASH memory driver`s parameters, this function 
+* 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. 
+*             flashMode - PURE8, X8 or X16.
 * RETURNS:    Flash Size, zero when operation (flashInit) failed.
 *********************************************************************/
 unsigned int flashInit(unsigned int flashBaseAddress,
@@ -229,10 +229,10 @@
 		break;
 
 	}
-	/* Try to locate the device in the supported flashes list (FLASH_TYPE). 
-	   according to the keys: 
+	/* Try to locate the device in the supported flashes list (FLASH_TYPE).
+	   according to the keys:
 	   1) mfrId - manufactor ID.
-	   2) devId - device ID.  
+	   2) devId - device ID.
 	 */
 
 	while (true) {
@@ -266,9 +266,9 @@
 
 /********************************************************************
 * flashReset - Resets the Flash memory (FLASH`s internal protocol reset).
-*                
-* INTPUTS:  N/A    
-* OUTPUT:   N/A  
+*
+* INTPUTS:  N/A
+* OUTPUT:   N/A
 *********************************************************************/
 void flashReset()
 {
@@ -771,7 +771,7 @@
 * 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 
+*				   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
 *
@@ -899,7 +899,7 @@
 				}
 			}
 			break;
-		case 2:	/* Split the 32 bit write into two 8/16 bit Writings 
+		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    */
@@ -1269,7 +1269,7 @@
 }
 
 /********************************************************************
-* flashReadWord - Read 32Bit from the FLASH memory at a given offset 
+* 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
@@ -1288,7 +1288,7 @@
 * 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 
+* RETURNS: Sector number,or 0xffffffff in case the address is out of range or
 *          flash wasn't initialize.
 *********************************************************************/
 unsigned int flashInWhichSector(unsigned int offset)
@@ -1317,7 +1317,7 @@
 * 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 
+* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't
 *          initialize return 0.)
 *********************************************************************/
 unsigned int flashGetSectorSize(unsigned int sectorNumber)
@@ -1484,7 +1484,7 @@
 
 /********************************************************************
 * flashWriteShort - write 16bit data to a given flash offset.
-*                  It reads the whole word 32bit wide, modify the  short 
+*                  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.
@@ -1520,7 +1520,7 @@
 
 /********************************************************************
 * flashWriteChar - write one charecter (8 bit) to a given flash offset.
-*                  It reads the whole word 32bit wide, modify the charecter 
+*                  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.
@@ -1548,7 +1548,7 @@
 
 /********************************************************************
 * flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset.
-*                        It reads the whole word 32bit wide, modify the  
+*                        It reads the whole word 32bit wide, modify the
 *                        charecter and write back the word.
 *
 * INPUTS:  N/A.
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/head.S linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/head.S
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/head.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/head.S	Thu Sep 12 20:01:40 2002
@@ -9,11 +9,11 @@
 	.text
 NESTED(startup, 16, sp)
 	.set	noreorder
-        
+
 	jal decompress_kernel
 	nop
-        
+
         jal kernel_location_start+0x584
         nop
-        
+
 	END(startup)
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal	Thu Sep 12 20:01:40 2002
@@ -1,8 +1,8 @@
 OUTPUT_FORMAT("elf32-bigmips")
 OUTPUT_ARCH(mips)
 ENTRY(startup)
-SECTIONS 
-{ 
+SECTIONS
+{
   kernel_location_start = 0x80100000;
   . = 0x80400000;
   .text : {
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash	Thu Sep 12 20:01:40 2002
@@ -6,7 +6,7 @@
 {
   . = 0xBFC00000;
   .got : {*(.got)}
-  .reset : { 
+  .reset : {
     sbdreset = ABSOLUTE(.);
     sbdreset_evb64120A.o
     evb64120A_Setup.o /* <-- Note: contains xfer.c contents as well.. */
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2	Thu Sep 12 20:01:40 2002
@@ -6,7 +6,7 @@
 {
   . = 0xBF000000;
   .got : {*(.got)}
-  .reset : { 
+  .reset : {
     xfer.o
   }
   kernel_location_start = 0x80100000;
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/meminit.S linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/meminit.S
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/meminit.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/meminit.S	Thu Sep 12 20:01:40 2002
@@ -1,8 +1,8 @@
-/* 
- * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming 
+/*
+ * 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 
+ * prevents us reading back data sitting in the dram buffers and
  * getting a false match.
  */
 
@@ -17,11 +17,11 @@
 #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
@@ -36,13 +36,13 @@
 
 	li	t0,RAM_BASE+MEMSTART	# start at bottom of phys mem
 	move	t1,t0			# remember start address
-	li	t2,0xaa55aa55		# pattern 
+	li	t2,0xaa55aa55		# pattern
 	not	t3,t2			# ~pattern
 
 	move	t7,k0
 	la	t4,.fail		# bus error exception catcher
-	addu	k0,t4,s8		# RELOC 
-	
+	addu	k0,t4,s8		# RELOC
+
 	/* fill first 64Kb with zero (for cache init) */
 	move	t4,t0
 	li	t5,0x10000
@@ -55,7 +55,7 @@
 	bnez	t5,1b
 
 .loop:
-        addu    t0,MEMINCR		
+        addu    t0,MEMINCR
 	move	t4,t0
 
 	/* store pattern in bank 0, line 0 */
@@ -109,25 +109,25 @@
 
 
 /*
- * We must often initialise memory so that it has good parity/ecc, 
+ * 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_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:	
+clear_mem_range:
 	beqz	a0,9f
-	addu	a0,a1			# end of memory 
-	
+	addu	a0,a1			# end of memory
+
 	/* XXX should run cached, but caches may not be initialised yet */
-	.set noreorder	
+	.set noreorder
 #if __mips >= 3
 1:	sd	zero,0(a1)
 	sd	zero,8(a1)
@@ -139,7 +139,7 @@
 	addu	a1,64
 	bne	a1,a0,1b
 	sd	zero,-8(a1)		# BDSLOT
-#else	
+#else
 1:	sw	zero,0(a1)
 	sw	zero,4(a1)
 	sw	zero,8(a1)
@@ -158,7 +158,7 @@
 	addu	a1,64
 	bne	a1,a0,1b
 	sw	zero,-4(a1)		# BDSLOT
-#endif	
+#endif
 	.set	reorder
 
 9:	j	ra
@@ -172,7 +172,7 @@
         mtc0	zero,C0_PGMASK
 	li	t8,K1BASE		/* tlbhi  = impossible vpn */
 	li	t9,(NTLBENTRIES-1)	/* index */
-	
+
 	.set noreorder
 	nop
 1:	mtc0	t8,C0_TLBHI
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/memory.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/memory.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/memory.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/memory.c	Thu Sep 12 20:01:40 2002
@@ -8,7 +8,7 @@
 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!!!           
+mappings and make sure to coordinate between the two interfaces!!!
 */
 
 /* includes */
@@ -26,7 +26,7 @@
 *      - If the memory bank size is 0 then this base address has no meaning !!!
 *
 * INPUTS:  MEMORY_BANK bank - SDRAM Bank number.
-* OUTPUT:  N/A  
+* OUTPUT:  N/A
 * RETURNS: Memory bank base address.
 *********************************************************************/
 unsigned int getMemoryBankBaseAddress(MEMORY_BANK bank)
@@ -45,7 +45,7 @@
 *           - If the device size is 0 then this base address has no meaning!!!
 *
 * INPUT:   DEVICE device - Bank number.
-* OUTPUT:  N/A  
+* OUTPUT:  N/A
 * RETURNS: Device base address.
 *********************************************************************/
 unsigned int getDeviceBaseAddress(DEVICE device)
@@ -83,7 +83,7 @@
 * getDeviceSize - Extract the size of a device memory space
 *
 * INPUT:    DEVICE device - Device number
-* OUTPUT:   N/A  
+* OUTPUT:   N/A
 * RETURNS:  Size of a device memory space.
 *********************************************************************/
 unsigned int getDeviceSize(DEVICE device)
@@ -103,10 +103,10 @@
 * 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].                  
+*                  at bits: [21:20].
 *
 * INPUT:    DEVICE device - Device number
-* OUTPUT:   N/A  
+* OUTPUT:   N/A
 * RETURNS:  Device width in Bytes (1,2,4, or 8), 0 if error had occurred.
 *********************************************************************/
 unsigned int getDeviceWidth(DEVICE device)
@@ -132,9 +132,9 @@
 
 /********************************************************************
 * mapMemoryBanks0and1 - Sets new bases and boundaries for memory banks 0 and 1
-*                     - Pay attention to the PCI mappings and make sure to 
+*                     - Pay attention to the PCI mappings and make sure to
 *                       coordinate between the two interfaces!!!
-*                     - It is the programmer`s responsibility to make sure 
+*                     - 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
 *
@@ -143,7 +143,7 @@
 *         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 
+* RETURNS: true on success, false on failure or if one of the parameters is
 *          erroneous.
 *********************************************************************/
 bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length,
@@ -205,7 +205,7 @@
 
 /********************************************************************
 * mapMemoryBanks2and3 - Sets new bases and boundaries for memory banks 2 and 3
-*                     - Pay attention to the PCI mappings and make sure to  
+*                     - 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!!!
@@ -216,7 +216,7 @@
 *         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 
+* RETURNS: true on success, false on failure or if one of the parameters is
 *          erroneous.
 *********************************************************************/
 bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length,
@@ -278,9 +278,9 @@
 }
 
 /********************************************************************
-* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1 
+* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1
 *                                and 2
-*                     - Pay attention to the PCI mappings and make sure to 
+*                     - 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!!!
@@ -289,11 +289,11 @@
 *
 * 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 
+*         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,
@@ -431,11 +431,11 @@
 }
 
 /********************************************************************
-* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices: 
+* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices:
 *                                 3 and boot
-*                     - Pay attention to the PCI mappings and make sure to 
+*                     - Pay attention to the PCI mappings and make sure to
 *                       coordinate between the two interfaces!!!
-*                     - It is the programmer`s responsibility to make sure 
+*                     - 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.
 *
@@ -501,7 +501,7 @@
 }
 
 /********************************************************************
-* modifyDeviceParameters - This function can be used to modify a device`s 
+* modifyDeviceParameters - This function can be used to modify a device`s
 *                          parameters.
 *                        - Be advised to check the spec before modifying them.
 * Inputs:
@@ -579,8 +579,8 @@
 }
 
 /********************************************************************
-* remapAddress - This fubction used for address remapping 
-* Inputs:      - regOffset: remap register 
+* 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.
 *********************************************************************/
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/misc.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/misc.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/misc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/misc.c	Thu Sep 12 20:01:40 2002
@@ -1,7 +1,7 @@
 /*
  * arch/mips/galileo/misc.c
- * 
- * This is a collection of several routines from gzip-1.0.3 
+ *
+ * This is a collection of several routines from gzip-1.0.3
  * adapted for Linux.
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/pci.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/pci.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/pci.c	Thu Sep 12 20:01:40 2002
@@ -25,12 +25,12 @@
 
 /********************************************************************
 * pci0ScanDevices   - This function scan PCI0 bus, if found any device on
-*                     this bus it interrogate the Device for the information 
+*                     this bus it interrogate the Device for the information
 *                     it can discover.
-*                     The fields with all information are the following: 
+*                     The fields with all information are the following:
 *    char            type[20];
 *    unsigned int    deviceNum;
-*    unsigned int    venID;                                            
+*    unsigned int    venID;
 *    unsigned int    deviceID;
 *    unsigned int    bar0Base;
 *    unsigned int    bar0Size;
@@ -44,7 +44,7 @@
 *    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.
@@ -307,12 +307,12 @@
 
 /********************************************************************
 * pci1ScanDevices   - This function scan PCI1 bus, if found any device on
-*                     this bus it interrogate the Device for the information 
+*                     this bus it interrogate the Device for the information
 *                     it can discover.
-*                     The fields with all information are the following: 
+*                     The fields with all information are the following:
 *    char            type[20];
 *    unsigned int    deviceNum;
-*    unsigned int    venID;                                            
+*    unsigned int    venID;
 *    unsigned int    deviceID;
 *    unsigned int    bar0Base;
 *    unsigned int    bar0Size;
@@ -326,8 +326,8 @@
 *    unsigned int    bar4Size;
 *    unsigned int    bar5Base;
 *    unsigned int    bar5Size;
-* 
-* Inputs:   Pointer to an array of STRUCT PCI1_DEVICE. 
+*
+* Inputs:   Pointer to an array of STRUCT PCI1_DEVICE.
 * Output:   None.
 *********************************************************************/
 
@@ -562,12 +562,12 @@
 
 /********************************************************************
 * pci0WriteConfigReg - Write to a PCI configuration register
-*                    - Make sure the GT is configured as a master before 
+*                    - 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 
+* 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.                
+*           pciDevNum: The device number needs to be addressed.
 *
 *  Configuration Address 0xCF8:
 *
@@ -604,9 +604,9 @@
 *                   - 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  
+* 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.                
+*           pciDevNum: The device number needs to be addressed.
 *
 *  Configuration Address 0xCF8:
 *
@@ -626,7 +626,7 @@
 	pciDevNum = pciDevNum << 11;
 	regOffset = regOffset & 0x0fffffff;
 	if (pciDevNum == SELF) {	/* This board */
-		/* when configurating our own PCI 1 L-unit the access is through  
+		/* 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;
@@ -647,13 +647,13 @@
 
 /********************************************************************
 * pci0ReadConfigReg  - Read from a PCI0 configuration register
-*                    - Make sure the GT is configured as a master before 
+*                    - 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 
+*           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:
@@ -690,13 +690,13 @@
 
 /********************************************************************
 * pci1ReadConfigReg  - Read from a PCI1 configuration register
-*                    - Make sure the GT is configured as a master before 
+*                    - 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 
+*           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:
@@ -718,7 +718,7 @@
 	pciDevNum = pciDevNum << 11;
 	regOffset = regOffset & 0x0fffffff;
 	if (pciDevNum == SELF) {	/* This board */
-		/* when configurating our own PCI 1 L-unit the access is through  
+		/* 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;
@@ -1058,7 +1058,7 @@
 }
 
 /********************************************************************
-* pci0MapInternalRegSpace - Maps the internal registers memory space for the 
+* 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
@@ -1078,7 +1078,7 @@
 }
 
 /********************************************************************
-* pci1MapInternalRegSpace - Maps the internal registers memory space for the 
+* 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
@@ -1098,7 +1098,7 @@
 }
 
 /********************************************************************
-* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
+* 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
@@ -1117,7 +1117,7 @@
 }
 
 /********************************************************************
-* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the 
+* 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
@@ -1137,7 +1137,7 @@
 
 /********************************************************************
 * pci0MapMemoryBanks0_1 - Maps PCI0 memory banks 0 and 1 for the slave.
-*                         for Discovery we need two function: SCS0 & SCS1 
+*                         for Discovery we need two function: SCS0 & SCS1
 *                         (instead of SCS[1:0])
 * Inputs: base and size of pci0 dram
 *********************************************************************/
@@ -1163,7 +1163,7 @@
 
 /********************************************************************
 * pci1MapMemoryBanks0_1 - Maps PCI1 memory banks 0 and 1 for the slave.
-*                         for Discovery we need two function: SCS0 & SCS1 
+*                         for Discovery we need two function: SCS0 & SCS1
 *                         (instead of SCS[1:0])
 * Inputs: base and size of pci1 dram
 *********************************************************************/
@@ -1188,7 +1188,7 @@
 
 /********************************************************************
 * pci0MapMemoryBanks2_3 - Maps PCI0 memory banks 2 and 3 for the slave.
-*                         for Discovery we need two function: SCS2 & SCS3 
+*                         for Discovery we need two function: SCS2 & SCS3
 *                         (instead of SCS[3:2])
 * Inputs: base and size of pci0 dram
 *********************************************************************/
@@ -1213,7 +1213,7 @@
 
 /********************************************************************
 * pci1MapMemoryBanks2_3 - Maps PCI1 memory banks 2 and 3 for the slave.
-*                         for Discovery we need two function: SCS2 & SCS3 
+*                         for Discovery we need two function: SCS2 & SCS3
 *                         (instead of SCS[3:2])
 * Inputs: base and size of pci1 dram
 *********************************************************************/
@@ -1237,7 +1237,7 @@
 }
 
 /********************************************************************
-* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces 
+* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces
 *                                    for the slave.
 *                                    For the Discovery there are 3 separate
 *                                    fucnction's
@@ -1260,7 +1260,7 @@
 }
 
 /********************************************************************
-* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces 
+* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces
 *                                    for the slave.
 *                                    For the Discovery there are 3 separate
 *                                    fucnction's
@@ -1282,9 +1282,9 @@
 }
 
 /********************************************************************
-* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory 
+* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory
 *                                     spaces for the slave.
-*                                     For the Discovery there are 2 separate 
+*                                     For the Discovery there are 2 separate
 *                                     fucnction's
 * Inputs: base and length of pci0 device3/ boot
 *********************************************************************/
@@ -1309,9 +1309,9 @@
 }
 
 /********************************************************************
-* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory 
+* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory
 *                                     spaces for the slave.
-*                                     For the Discovery there are 2 separate 
+*                                     For the Discovery there are 2 separate
 *                                     fucnction's
 * Inputs: base and length of pci1 device3/ boot
 *********************************************************************/
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c	Thu Sep 12 20:01:40 2002
@@ -21,7 +21,7 @@
 	if ((bus == 0) && (dev >= 0) && (dev < 30))
 		return 0;	// Bus/Device Number OK
 
-	return -1;		// Bus/Device Number not OK  
+	return -1;		// Bus/Device Number not OK
 }
 
 /********************************************************************
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S	Thu Sep 12 20:01:40 2002
@@ -1,7 +1,7 @@
 /*
  * Copyright 1997 Algorithmics Ltd
  *	All Rights Reserved
- *	
+ *
  * gal9/sbdreset.sx -- low level board dependent routines
  */
 
@@ -23,29 +23,29 @@
 
 #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_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 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 SBD_DISPLAY(a,b,c,d,e) ;
 
 #define K0BASE          0x80000000
 #define K0SIZE          0x20000000
@@ -70,7 +70,7 @@
 #endif
 
 #define MB	0x100000
-				
+
 #define MemTypeNone		0x8000
 #define MemRasMask		0x0f00
 #define MemRasShift		8
@@ -85,7 +85,7 @@
 #define bank3	s5
 #define memtop	s6
 #define membase	s7
-	
+
 /*#if #endian(big)	*/
 #ifdef __MIPSEB__
 
@@ -104,9 +104,9 @@
 #else
 #define HTOLL(sr,tr)
 #endif
-				
+
 #undef DBGSBD
-	
+
 #ifdef DBGSBD
 #define DBG(s) \
 	.rdata ; \
@@ -114,7 +114,7 @@
 	.text ; \
 	la	a0, 88b ; \
 	jal	_dbgmsg
-	
+
 LEAF(_dbgmsg)
 	.set noat
 	li	AT,PHYS_TO_K1(NS16550_CHANB)
@@ -123,13 +123,13 @@
 	.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	
+	b	waitrdy
 9:	j	ra
 	.set at
 END(_dbgmsg)
@@ -142,7 +142,7 @@
 	.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
@@ -153,11 +153,11 @@
 	sll	a0,4
 	sub	t0,1
 	bnez	t0,1b
-		
+
 	j	ra
 	.set at
 END(_dbghex)
-	
+
 	.rdata
 initb_str:
 	.byte	9,0x40	/* Reset CH B */
@@ -171,7 +171,7 @@
 	.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 */
@@ -179,7 +179,7 @@
 	.byte	0xff
 
 	.text
-	
+
 SLEAF(_dbginit)
         /*
         li	v0,PHYS_TO_K1(NS16550_CHANB)
@@ -194,27 +194,27 @@
         */
         jal     init_ns16550_chan_b # Debug channel
 	j	ra
-SEND(_dbginit)		
+SEND(_dbginit)
 #else
-#define DBG(s)		
+#define DBG(s)
 #endif
-		
+
 LEAF(sbdreset)
 	move	rasave,ra
 
 	/* if launched by ITROM, leave Config alone */
-#ifndef ITBASE	
+#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	
+#endif
+
+       /* Initialize stack pointer to 6MB address */
+         li sp,0xa0600000
 
-       /* Initialize stack pointer to 6MB address */        
-         li sp,0xa0600000 
 
-        
         /*
 	 * slight amount of kludgery here to stop RAM resident
 	 * program from overwriting itself...
@@ -248,23 +248,23 @@
 #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)
@@ -274,14 +274,14 @@
 	sw  t0,0(v0)
 
         /* GT-64120 Initialization */
-        
-        li      p64011, PA_TO_KVA1(GT64011_BASE)	
+
+        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)                  */
@@ -292,76 +292,76 @@
                                         /* - 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  v0,0xb4000008
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000010      
+
+        li  v0,0xb4000010
 	li  t0,htoll(0x7f)
 	sw  t0,0(v0)
-        
+
         /* Close banks 2 and 3 */
-        li  v0,0xb4000018      
+        li  v0,0xb4000018
 	li  t0,htoll(0x7ff)
 	sw  t0,0(v0)
-        li  v0,0xb4000020      
+        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  v0,0xb4000400
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        li  v0,0xb4000404      
+        li  v0,0xb4000404
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        li  v0,0xb4000408      
+        li  v0,0xb4000408
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400040c      
+	sw  t0,0(v0)
+        li  v0,0xb400040c
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000410      
+        li  v0,0xb4000410
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb4000414      
+	sw  t0,0(v0)
+        li  v0,0xb4000414
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000418      
+        li  v0,0xb4000418
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400041c      
+	sw  t0,0(v0)
+        li  v0,0xb400041c
 	li  t0,htoll(0x00)
-	sw  t0,0(v0)        
+	sw  t0,0(v0)
 
         /* Configure bank0 to 256 Mbit */
         DBG("Configure bank0 to 256 Mbit...\r\n")
-        li  v0,0xb400044c      
+        li  v0,0xb400044c
 	li  t0,htoll(0x00004c69)
         sw  t0,0(v0)
-        
+
         /* Config the SDRAM banks decode system */
-	li  v0,0xb400047c      
+	li  v0,0xb400047c
 	li  t0,htoll(2)
 	sw  t0,0(v0)
- 
-        li  v0,0xb4000474        
+
+        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  v0,0xb4000474
 	li  t0,htoll(0x0)
-	sw  t0,0(v0)      
-        
+	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
@@ -372,7 +372,7 @@
         bne t1,v0,1b
 
         /* The address should activate Dadr12 */
-        li  v0,0xa2000000      
+        li  v0,0xa2000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -387,7 +387,7 @@
         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
@@ -398,7 +398,7 @@
         bne t1,v0,1b
 
         /* The address should activate bank select1*/
-        li  v0,0xa0001000      
+        li  v0,0xa0001000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -425,7 +425,7 @@
 
         /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
            device */
-        li  v0,0xa8000000      
+        li  v0,0xa8000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -441,11 +441,11 @@
         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  v0,0xb4000810
 	li  t0,htoll(16)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000449)
@@ -454,7 +454,7 @@
 _64MBIT:
         DBG("64 Mbit SDRAM detected...\r\n")
         /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(64)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -463,7 +463,7 @@
 _128MBIT:
         DBG("128 Mbit SDRAM detected...\r\n")
         /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(128)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -472,85 +472,85 @@
 _256MBIT:
         DBG("256 Mbit SDRAM detected...\r\n")
         /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000810      
+        li  v0,0xb4000810
 	li  t0,htoll(256)
 	sw  t0,0(v0)
         li  t1,htoll(0x00004c69)
         b   _DIMM1
-        
-_DIMM1:        
+
+_DIMM1:
         li  v0,0xb400044c
         sw  t1,0(v0)  # Bank0
-        sw  t1,4(v0)  # Bank1           
-        
+        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  v0,0xb4000008
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000010      
+
+        li  v0,0xb4000010
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
+
         /* Set bank2`s range to: 0 - 0x10000000 (256 MByte)     */
-        li  v0,0xb4000018      
+        li  v0,0xb4000018
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        li  v0,0xb4000020      
+        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  v0,0xb4000400
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        li  v0,0xb4000404      
+        li  v0,0xb4000404
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000408      
+        li  v0,0xb4000408
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400040c      
+	sw  t0,0(v0)
+        li  v0,0xb400040c
 	li  t0,htoll(0x00)
 	sw  t0,0(v0)
-        li  v0,0xb4000410      
+        li  v0,0xb4000410
 	li  t0,htoll(0x00)
-	sw  t0,0(v0)   
-        li  v0,0xb4000414      
+	sw  t0,0(v0)
+        li  v0,0xb4000414
 	li  t0,htoll(0xff)
 	sw  t0,0(v0)
-        li  v0,0xb4000418      
+        li  v0,0xb4000418
 	li  t0,htoll(0xff)
-	sw  t0,0(v0)   
-        li  v0,0xb400041c      
+	sw  t0,0(v0)
+        li  v0,0xb400041c
 	li  t0,htoll(0x00)
-	sw  t0,0(v0)        
+	sw  t0,0(v0)
 
         /* Configure bank2 to 256 Mbit */
         DBG("Configure bank2 to 256 Mbit...\r\n")
-        li  v0,0xb4000454      
+        li  v0,0xb4000454
 	li  t0,htoll(0x00004c69)
         sw  t0,0(v0)
-        
+
         /* Config the SDRAM banks decode system */
-	li  v0,0xb400047c      
+	li  v0,0xb400047c
 	li  t0,htoll(2)
 	sw  t0,0(v0)
- 
-        li  v0,0xb4000474        
+
+        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  v0,0xb4000474
 	li  t0,htoll(0x0)
-	sw  t0,0(v0)      
-        
+	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
@@ -561,7 +561,7 @@
         bne t1,v0,1b
 
         /* The address should activate Dadr12 */
-        li  v0,0xa2000000      
+        li  v0,0xa2000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -576,7 +576,7 @@
         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
@@ -587,7 +587,7 @@
         bne t1,v0,1b
 
         /* The address should activate bank select1*/
-        li  v0,0xa0001000      
+        li  v0,0xa0001000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -614,7 +614,7 @@
 
         /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
            device */
-        li  v0,0xa8000000      
+        li  v0,0xa8000000
 	li  t0,0x11111111
         sw  t0,0(v0)
         li  v0,0xa0000010
@@ -630,11 +630,11 @@
         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  v0,0xb4000814
 	li  t0,htoll(16)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000449)
@@ -643,7 +643,7 @@
 _64MBIT2:
         DBG("64 Mbit SDRAM detected...\r\n")
         /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(64)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -652,7 +652,7 @@
 _128MBIT2:
         DBG("128 Mbit SDRAM detected...\r\n")
         /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(128)
 	sw  t0,0(v0)
         li  t1,htoll(0x00000c69)
@@ -661,104 +661,104 @@
 _256MBIT2:
         DBG("256 Mbit SDRAM detected...\r\n")
         /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
-        li  v0,0xb4000814      
+        li  v0,0xb4000814
 	li  t0,htoll(256)
 	sw  t0,0(v0)
         li  t1,htoll(0x00004c69)
         b   _INIT_SDRAM
 
-_INIT_SDRAM:        
+_INIT_SDRAM:
         /* Restore defaults */
         DBG("Restoring defaults...\r\n")
-        li  v0,0xb4000404      
+        li  v0,0xb4000404
 	li  t0,htoll(0x07)
 	sw  t0,0(v0)
-        li  v0,0xb4000408      
+        li  v0,0xb4000408
 	li  t0,htoll(0x08)
 	sw  t0,0(v0)
-        li  v0,0xb400040c      
+        li  v0,0xb400040c
 	li  t0,htoll(0x0f)
 	sw  t0,0(v0)
-        li  v0,0xb4000410      
+        li  v0,0xb4000410
 	li  t0,htoll(0x10)
-	sw  t0,0(v0)   
-        li  v0,0xb4000414      
+	sw  t0,0(v0)
+        li  v0,0xb4000414
 	li  t0,htoll(0x17)
 	sw  t0,0(v0)
-        li  v0,0xb4000418      
+        li  v0,0xb4000418
 	li  t0,htoll(0x18)
-	sw  t0,0(v0)   
-        li  v0,0xb400041c      
+	sw  t0,0(v0)
+        li  v0,0xb400041c
 	li  t0,htoll(0x1f)
 	sw  t0,0(v0)
-        li  v0,0xb4000010      
+        li  v0,0xb4000010
 	li  t0,htoll(0x07)
 	sw  t0,0(v0)
-        li  v0,0xb4000018      
+        li  v0,0xb4000018
 	li  t0,htoll(0x008)
 	sw  t0,0(v0)
-        li  v0,0xb4000020      
+        li  v0,0xb4000020
 	li  t0,htoll(0x0f)
-	sw  t0,0(v0)        
-        
+	sw  t0,0(v0)
+
         li  v0,0xb400044c
         sw  t1,8(v0)  # Bank2
         sw  t1,12(v0) # Bank3
-        
-        li  v0,0xb4000474        
+
+        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  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        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  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        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  v0,0xb4000474
 	li  t0,htoll(0x0)
 	sw  t0,0(v0)
-        
-        li  v0,0xb4000474        
+
+        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  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)
 
@@ -794,8 +794,8 @@
 
         li      t0,htoll(0x0000001f)    /* RAS[3] High Decode Address <<<<<< 1*/
         sw      t0,0x41c(p64011)
-	
-#ifdef DBGSBD	
+
+#ifdef DBGSBD
 #define DREG(str,rname) \
 	DBG(str); \
 	DBG(":\t") ;			\
@@ -803,7 +803,7 @@
 	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)
@@ -828,7 +828,7 @@
         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")
@@ -839,7 +839,7 @@
 	/* initialise tlb */
 	SBD_DISPLAY ('I','T','L','B', CHKPNT_ITLB)
 	DBG("init_tlb\r\n")
-//	bal	init_tlb 
+//	bal	init_tlb
 
 //	DBG("sbdreset completed\r\n")
 //	move	ra,rasave
@@ -928,7 +928,7 @@
 
 LEAF(sbdberrenb)
 	mfc0	v0,C0_SR
-	li	t0,SR_DE	
+	li	t0,SR_DE
 	bnez	a0,1f
 	or	t1,v0,t0	# disable cache/parity errors (SR_DE = 1)
 	b	2f
@@ -966,7 +966,7 @@
 1:	mul	a0,t1
 	subu	a0,15		# approx number of loops so far
 
-	.set	noreorder	
+	.set	noreorder
 	.set	nomacro
 	nop
 2:	bgtz	a0,2b
@@ -981,7 +981,7 @@
 
 
 LEAF(mips_cycle)
-	.set	noreorder	
+	.set	noreorder
 	.set	nomacro
 1:	bgtz	a0,1b
 	subu	a0,1
@@ -992,7 +992,7 @@
 
 LEAF(init_ns16550_chan_b)
 	# enable 16550 fifo if it is there
-        li      a0,NS16550_CHANB 
+        li      a0,NS16550_CHANB
         li	t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
 	sb	t0,FIFO(a0)
 
@@ -1002,25 +1002,25 @@
 	li	t0,CFCR_DLAB			# select brtc divisor
 	sb	t0,CFCR(a0)
 	sb	t2,DATA(a0)			# store divisor lsb
-	srl	t2,8	
+	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 
+	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(!) 
+ 	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      a0,NS16550_CHANA
         li	t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
 	sb	t0,FIFO(a0)
 
@@ -1030,20 +1030,20 @@
 	li	t0,CFCR_DLAB			# select brtc divisor
 	sb	t0,CFCR(a0)
 	sb	t2,DATA(a0)			# store divisor lsb
-	srl	t2,8	
+	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 
+	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(!) 
+ 	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 -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/dma.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/dma.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/dma.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/dma.c	Thu Sep 12 20:01:40 2002
@@ -6,7 +6,7 @@
 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 
+To fully understand the capabilities of the DMA engines please spare some
 time to go trough the spec.
 */
 
@@ -20,11 +20,11 @@
 #include "DMA.h"
 #endif
 /********************************************************************
-* dmaCommand - Write a command to a DMA channel 
+* 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. 
+* Returns: false if one of the parameters is erroneous else returns true.
 *********************************************************************/
 
 bool dmaCommand(DMA_ENGINE channel, unsigned int command)
@@ -39,14 +39,14 @@
 * 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 
+*   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 
+*   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 
+*   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;
@@ -149,10 +149,10 @@
 
 
 /********************************************************************
-* changeDmaPriority - update the arbiter`s priority for channels 0-3 
+* 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   
+* 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
 *********************************************************************/
 
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/i2o.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/i2o.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/i2o.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/i2o.c	Thu Sep 12 20:01:40 2002
@@ -21,7 +21,7 @@
 *                     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.
@@ -37,12 +37,12 @@
 
 
 /********************************************************************
-* checkInboundIntAndClear - When a message is received an interrupt is 
+* 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
@@ -76,9 +76,9 @@
 *                     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.   
+*         unsigned int message - Message to be sent.
 * OUTPUT: N/A.
 * RETURNS: true.
 *********************************************************************/
@@ -94,7 +94,7 @@
 * 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. 
+*                    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.
 *
@@ -124,8 +124,8 @@
 /********************************************************************
 * maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking
 *                               the interrupt you can work in polling mode
-*                               using the checkInboundIntAndClear function. 
-* 
+*                               using the checkInboundIntAndClear function.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -146,8 +146,8 @@
 }
 
 /********************************************************************
-* enableInBoundMessageInterrupt - unMask the inbound interrupt. 
-* 
+* enableInBoundMessageInterrupt - unMask the inbound interrupt.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -170,8 +170,8 @@
 /********************************************************************
 * 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. 
-* 
+*                           cause register to monitor an incoming message.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -194,8 +194,8 @@
 /********************************************************************
 * 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. 
-* 
+*                           cause register to monitor an incoming message.
+*
 * INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
 * OUTPUT: N/A.
 * RETURNS: true.
@@ -216,13 +216,13 @@
 }
 
 /********************************************************************
-* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the 
+* 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.
@@ -236,7 +236,7 @@
 /********************************************************************
 * readInBoundDoorBellInt - Read the in bound door bell interrupt cause
 *                          register.
-* 
+*
 * OUTPUT:  N/A.
 * RETURNS: The 32 bit interrupt cause register.
 *********************************************************************/
@@ -253,7 +253,7 @@
 *                           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.
@@ -282,11 +282,11 @@
 }
 
 /********************************************************************
-* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is 
+* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is
 *                                  set, can be used for acknowledging interrupt
 *                                  handling by the agent who recieived the
-*                                  interrupt. 
-* 
+*                                  interrupt.
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: true if the corresponding bit in the cause register is set otherwise
@@ -354,7 +354,7 @@
 
 /********************************************************************
 * 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
@@ -364,7 +364,7 @@
 *           Inbound Free = queueBaseAddr
 *           Inbound Post = queueBaseAddr + cirQueSize
 *           Outbound Post = queueBaseAddr + cirQueSize
-*           
+*
 * OUTPUT:  N/A.
 * RETURNS: true.
 *
@@ -410,10 +410,10 @@
 }
 
 /********************************************************************
-* inBoundPostQueuePop - Two actions are being taken upon pop: 
+* 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) 
+*              incremented automaticaly by the GT)
 *
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
@@ -469,7 +469,7 @@
 
 /********************************************************************
 * clearInBoundPostQueueInterrupt - Clears the Post queue interrupt.
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS: true.
@@ -486,7 +486,7 @@
 *
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
-* RETURNS: 
+* RETURNS:
 *********************************************************************/
 void maskInBoundPostQueueInterrupt()
 {
@@ -501,7 +501,7 @@
 /********************************************************************
 * enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new
 *                                   message from the PCI agent.
-* 
+*
 * INPUTS:  N/A.
 * OUTPUT:  N/A.
 * RETURNS:
@@ -516,11 +516,11 @@
 }
 
 /********************************************************************
-* inBoundFreeQueuePush - Two actions are being taken upon push: 
+* 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.
@@ -558,7 +558,7 @@
 * 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.
@@ -579,12 +579,12 @@
 }
 
 /********************************************************************
-* outBoundPostQueuePush  - Two actions are being taken upon push: 
+* 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.
@@ -622,7 +622,7 @@
 * 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.
@@ -643,11 +643,11 @@
 }
 
 /********************************************************************
-* outBoundFreeQueuePop - Two actions are being taken upon pop: 
+* 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.
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/int-handler.S linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/int-handler.S
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/int-handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/int-handler.S	Thu Sep 12 20:01:40 2002
@@ -21,11 +21,11 @@
 		SAVE_ALL
 		CLI
 		.set	at
-		mfc0	t0,CP0_CAUSE  
+		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 */
@@ -42,7 +42,7 @@
 		j	spurious_interrupt
 		nop
 		END(galileo_handle_int)
-	
+
 
 		.align	5
 		.set	reorder
@@ -57,7 +57,7 @@
 		.align	5
 		.set	reorder
 ll_compare_irq:
-		li 	a0,7	
+		li 	a0,7
 		move	a1,sp
 		jal	do_IRQ
 		nop
@@ -76,7 +76,7 @@
 #if 0
 		.align	5
 		.set	reorder
-ll_pci_intB:	
+ll_pci_intB:
 		move 	a0,sp
 		jal	pci_intB
 		nop
@@ -85,14 +85,14 @@
 
 		.align	5
 		.set	reorder
-ll_pci_intC:	
+ll_pci_intC:
 		move 	a0,sp
 		jal	pci_intC
 		nop
 		j	ret_from_irq
 		nop
 #endif
-        
+
 		.align	5
 		.set	reorder
 ll_pci_intD:
@@ -101,10 +101,10 @@
 		nop
 		j	ret_from_irq
 		nop
-	
+
 		.align	5
 		.set	reorder
-ll_serial_irq:	
+ll_serial_irq:
 		li	a0,6
 		move	a1,sp
 		jal	do_IRQ
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/irq-handler.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/irq-handler.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/irq-handler.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/irq-handler.c	Thu Sep 12 20:01:40 2002
@@ -33,8 +33,8 @@
  * 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. 
+ * 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
  *
@@ -52,7 +52,7 @@
  * Enables the IRQ on Galileo Chip
  *
  * Inputs :
- * int_cause -  The interrupt cause number. In EVB64120 two parameters 
+ * 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
  *
@@ -77,7 +77,7 @@
  * Disables the IRQ on Galileo Chip
  *
  * Inputs :
- * int_cause -  The interrupt cause number. In EVB64120 two parameters 
+ * 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
  *
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/irq.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/irq.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/irq.c	Thu Sep 12 20:01:40 2002
@@ -65,7 +65,7 @@
 /*  Duplicate interrupt handlers.  */
 /********************************************************************
  *pci_int(A/B/C/D) -
- *	
+ *
  *Calls all the handlers connected to PCI interrupt A/B/C/D
  *
  *Inputs :
@@ -175,7 +175,7 @@
 	end:no_irq_enable_disable,
 };
 
-//      ack:            no_irq_ack,                re-enable later -- SKJ  
+//      ack:            no_irq_ack,                re-enable later -- SKJ
 
 
 /*
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/pci_bios.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/pci_bios.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/pci_bios.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/pci_bios.c	Thu Sep 12 20:01:40 2002
@@ -441,7 +441,7 @@
  * pci_range_ck -
  *
  * Check if the pci device that are trying to access does really exists
- * on the evaluation board.  
+ * on the evaluation board.
  *
  * Inputs :
  * bus - bus number (0 for PCI 0 ; 1 for PCI 1)
@@ -455,18 +455,18 @@
 	//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  
+	return -1;		// Bus/Device Number not OK
 }
 
 /*
  * pciXReadConfigReg  - Read from a PCI configuration register
- *                    - Make sure the GT is configured as a master before 
+ *                    - 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 
+ *           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:
@@ -518,7 +518,7 @@
 	   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  
+		/* 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);
@@ -538,13 +538,13 @@
 
 /*
  * pciXWriteConfigReg - Write to a PCI configuration register
- *                    - Make sure the GT is configured as a master before 
+ *                    - 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 
+ *           GT spec
  *                   (or any other PCI device spec)
- *           pciDevNum: The device number needs to be addressed.                
+ *           pciDevNum: The device number needs to be addressed.
  *
  *  Configuration Address 0xCF8:
  *
@@ -584,7 +584,7 @@
 	   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  
+		/* 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);
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/promcon.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/promcon.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/promcon.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/promcon.c	Thu Sep 12 20:01:40 2002
@@ -5,7 +5,7 @@
  * Copyright (c) 1999 Ulf Carlsson
  *
  * Derived from DECstation promcon.c
- * Copyright (c) 1998 Harald Koerfgen 
+ * Copyright (c) 1998 Harald Koerfgen
  */
 #include <linux/tty.h>
 #include <linux/major.h>
@@ -51,8 +51,8 @@
 
 void gal_serial_console_init(void)
 {
-	//  serial_init(); 
-	//serial_set(115200); 
+	//  serial_init();
+	//serial_set(115200);
 
 	register_console(&sercons);
 }
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/serialGT.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/serialGT.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/serialGT.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/serialGT.c	Thu Sep 12 20:01:40 2002
@@ -3,7 +3,7 @@
  *
  * BRIEF MODULE DESCRIPTION
  *  Low Level Serial Port control for use
- *  with the Galileo EVB64120A MIPS eval board and 
+ *  with the Galileo EVB64120A MIPS eval board and
  *  its on board two channel 16552 Uart.
  *
  * Copyright (C) 2000 RidgeRun, Inc.
@@ -139,7 +139,7 @@
 
 #if 0
 	/*
-	 * Set baud rate 
+	 * Set baud rate
 	 */
 	outreg(channel, LCR, LCR_DLAB | sav_lcr);
 	//  outreg(DLL,(XTAL/(16*2*(baud))-2));
@@ -149,7 +149,7 @@
 #else
 	/*
 	 * Note: Set baud rate, hardcoded here for rate of 115200
-	 * since became unsure of above "buad rate" algorithm (??). 
+	 * since became unsure of above "buad rate" algorithm (??).
 	 */
 	outreg(channel, LCR, 0x83);
 	outreg(channel, DLM, 0x00);	// See note above
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/setup.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/setup.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev64120/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/setup.c	Thu Sep 12 20:01:40 2002
@@ -61,7 +61,7 @@
 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
  */
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/init.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/init.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/init.c	Thu Sep 12 20:01:40 2002
@@ -3,7 +3,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/generic/generic.c
  *
  * Carsten Langgaard, carstenl@mips.com
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/irq.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/irq.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/irq.c	Thu Sep 12 20:01:40 2002
@@ -3,7 +3,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/atlas/atlas_int.c.
  *
  * Carsten Langgaard, carstenl@mips.com
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/pci_fixups.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/pci_fixups.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/pci_fixups.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/pci_fixups.c	Thu Sep 12 20:01:40 2002
@@ -72,19 +72,19 @@
 		pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
 
 #ifdef DEBUG
-		printk("devfn %x, slot %d devid %x\n", 
+		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, 
+			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, 
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
 					dev->irq);
 		}
 	}
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/pci_ops.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/pci_ops.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/pci_ops.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/pci_ops.c	Thu Sep 12 20:01:40 2002
@@ -7,7 +7,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/generic/pci.c
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -63,13 +63,13 @@
 #define GT_PCI_IO_BASE     0x10000000
 #define GT_PCI_IO_SIZE     0x02000000
 static struct resource pci_io_resource = {
-	"io pci IO space", 
+	"io pci IO space",
 	0x10000000,
 	0x10000000 + 0x02000000,
 	IORESOURCE_IO};
 
 static struct resource pci_mem_resource = {
-	"ext pci memory space", 
+	"ext pci memory space",
 	0x12000000,
 	0x12000000 + 0x02000000,
 	IORESOURCE_MEM};
@@ -95,11 +95,11 @@
         }
 
 	/* Clear cause register bits */
-	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
 	                             GT_INTRCAUSE_TARABORT0_BIT));
 
 	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	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)   |
@@ -112,7 +112,7 @@
 		*data = le32_to_cpu(*data);
 		}
 		GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
-	} 
+	}
         else {
 		GT_READ(GT_PCI0_CFGDATA_OFS, *data);
 		if (dev_fn != 0) {
@@ -131,7 +131,7 @@
 	        /* Error occured */
 
 	        /* Clear bits */
-	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | 
+	        GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
 					      GT_INTRCAUSE_TARABORT0_BIT) );
 
 		if (access_type == PCI_ACCESS_READ) {
@@ -158,7 +158,7 @@
 	}
 
 	*val = (data >> ((where & 3) << 3)) & 0xff;
-        DBG("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);
 
 	return PCIBIOS_SUCCESSFUL;
@@ -179,7 +179,7 @@
 	}
 
 	*val = (data >> ((where & 3) << 3)) & 0xffff;
-        DBG("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);
 
 	return PCIBIOS_SUCCESSFUL;
@@ -192,14 +192,14 @@
 
 	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", 
+        DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, *val);
 
 	return PCIBIOS_SUCCESSFUL;
@@ -210,13 +210,13 @@
 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", 
+        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))
@@ -232,13 +232,13 @@
 
 	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))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
-        DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n", 
+        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))
@@ -256,7 +256,7 @@
 
 	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", 
+        DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n",
                 dev->bus->number, dev->devfn, where, val);
 
 	return PCIBIOS_SUCCESSFUL;
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/setup.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/setup.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/setup.c	Thu Sep 12 20:01:40 2002
@@ -7,7 +7,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/atlas/atlas_setup.c.
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -52,8 +52,6 @@
 #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];
@@ -65,11 +63,6 @@
 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];
 
 
@@ -83,7 +76,6 @@
 	char *argptr;
 
 	clear_cp0_status(ST0_FR);
-        __wbflush = rm7000_wbflush;
 
         if (config & 0x8) {
             printk("Secondary cache is enabled\n");
@@ -144,7 +136,7 @@
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
-#endif	  
+#endif
 
 	rtc_ops = &no_rtc_ops;
 	mips_reboot_setup();
@@ -157,15 +149,15 @@
 #endif
 
 
-	/* 
-	 * setup gt controller master bit so we can do config cycles 
+	/*
+	 * 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_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
 	                             GT_INTRCAUSE_TARABORT0_BIT));
 	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	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)   |
@@ -174,9 +166,9 @@
 	udelay(2);
 	tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
 
-	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 
+	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
 		PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	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)   |
@@ -185,7 +177,7 @@
 	*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp);
 
 	/* Setup address */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	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)   |
@@ -195,12 +187,12 @@
 	tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS));
 }
 
-unsigned short get_gt_devid() 
+unsigned short get_gt_devid()
 {
 	u32 gt_devid;
 
 	/* Figure out if this is a gt96100 or gt96100A */
-	GT_WRITE(GT_PCI0_CFGADDR_OFS,  
+	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)   |
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/time.c linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/time.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/ev96100/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/ev96100/time.c	Thu Sep 12 20:01:40 2002
@@ -7,7 +7,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/atlas/atlas_rtc.c.
  *
  * Carsten Langgaard, carstenl@mips.com
@@ -67,9 +67,9 @@
 
 
 
-/* 
+/*
  * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
+ * register for each time tick.
  * Use the RTC to calculate offset.
  */
 static unsigned long __init cal_r4koff(void)
@@ -104,10 +104,10 @@
 
 	r4k_offset = cal_r4koff();
 
-	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, 
+	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);
 
@@ -184,7 +184,7 @@
 		 "r" (quotient));
 
 	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
+ 	 * 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)
@@ -260,7 +260,7 @@
 		r4k_cur += r4k_offset;
 		ack_r4ktimer(r4k_cur);
 
-	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) 
+	} while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
                     - r4k_cur) < 0x7fffffff);
 	return;
 
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/generic/Makefile linux-2.4.20-pre7/arch/mips/galileo-boards/generic/Makefile
--- linux-2.4.20-pre6/arch/mips/galileo-boards/generic/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/generic/Makefile	Thu Sep 12 20:01:40 2002
@@ -7,12 +7,12 @@
 # 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.
diff -urN linux-2.4.20-pre6/arch/mips/galileo-boards/generic/reset.c linux-2.4.20-pre7/arch/mips/galileo-boards/generic/reset.c
--- linux-2.4.20-pre6/arch/mips/galileo-boards/generic/reset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/galileo-boards/generic/reset.c	Thu Sep 12 20:01:40 2002
@@ -6,7 +6,7 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
- * This file was derived from Carsten Langgaard's 
+ * This file was derived from Carsten Langgaard's
  * arch/mips/mips-boards/generic/reset.c
  *
  * Carsten Langgaard, carstenl@mips.com
diff -urN linux-2.4.20-pre6/arch/mips/kernel/Makefile linux-2.4.20-pre7/arch/mips/kernel/Makefile
--- linux-2.4.20-pre6/arch/mips/kernel/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/Makefile	Thu Sep 12 20:01:40 2002
@@ -12,13 +12,12 @@
 
 O_TARGET := kernel.o
 
-export-objs			= irq.o pci-dma.o setup.o smp.o mips_ksyms.o \
-				  old-irq.o
+export-objs	= irq.o pci-dma.o setup.o smp.o mips_ksyms.o old-irq.o
+
+obj-y		+= branch.o cpu-probe.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-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
 
 obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
@@ -54,14 +53,14 @@
 
 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_REMOTE_DEBUG)	+= gdb-low.o gdb-stub.o
 obj-$(CONFIG_PROC_FS)		+= proc.o
 
 obj-$(CONFIG_NEW_PCI)		+= pci.o
+obj-$(CONFIG_PCI_AUTO)		+= pci_auto.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 -urN linux-2.4.20-pre6/arch/mips/kernel/cpu-probe.c linux-2.4.20-pre7/arch/mips/kernel/cpu-probe.c
--- linux-2.4.20-pre6/arch/mips/kernel/cpu-probe.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/kernel/cpu-probe.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,489 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <asm/bugs.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+/*
+ * 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;
+
+static void r3081_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
+}
+
+static void r39xx_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
+}
+
+static void r4k_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+}
+
+void au1k_wait(void)
+{
+#ifdef CONFIG_PM
+	/* using the wait instruction makes CP0 counter unusable */
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		"nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0");
+#else
+	__asm__("nop\n\t" "nop\n\t");
+#endif
+}
+
+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;
+	case CPU_AU1000:
+	case CPU_AU1100:
+	case CPU_AU1500:
+		cpu_wait = au1k_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.
+ * 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;
+}
+
+/*
+ * 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 = {
+    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;
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+
+__init void cpu_probe(void)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long config1;
+
+        if (config0 & (1 << 31)) {
+		/* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
+		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;
+#if defined(CONFIG_CPU_MIPS64)
+			mips_cpu.options |= MIPS_CPU_32FPR;
+#endif
+		}
+		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_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			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_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			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:
+			switch (mips_cpu.processor_id & 0xf0) {
+#ifndef CONFIG_VR4181
+			case PRID_REV_VR4111:
+				mips_cpu.cputype = CPU_VR4111;
+				break;
+#else
+			case PRID_REV_VR4181:
+				mips_cpu.cputype = CPU_VR4181;
+				break;
+#endif
+			case PRID_REV_VR4121:
+				mips_cpu.cputype = CPU_VR4121;
+				break;
+			case PRID_REV_VR4122:
+				if ((mips_cpu.processor_id & 0xf) < 0x3)
+					mips_cpu.cputype = CPU_VR4122;
+				else
+					mips_cpu.cputype = CPU_VR4181A;
+				break;
+			case PRID_REV_VR4131:
+				mips_cpu.cputype = CPU_VR4131;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+				break;
+			default:
+				printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+				mips_cpu.cputype = CPU_VR41XX;
+				break;
+			}
+                        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 weird 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;
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	case PRID_COMP_MIPS:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_4KC:
+			mips_cpu.cputype = CPU_4KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KEC:
+			mips_cpu.cputype = CPU_4KEC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KSC:
+			mips_cpu.cputype = CPU_4KSC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			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;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	case PRID_COMP_ALCHEMY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_AU1_REV1:
+		case PRID_IMP_AU1_REV2:
+			switch ((mips_cpu.processor_id >> 24) & 0xff) {
+			case 0:
+ 				mips_cpu.cputype = CPU_AU1000;
+				break;
+			case 1:
+				mips_cpu.cputype = CPU_AU1500;
+				break;
+			case 2:
+				mips_cpu.cputype = CPU_AU1100;
+				break;
+			default:
+				panic("Unknown Au Core!");
+				break;
+			}
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+ 			break;
+		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.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_cpu.cputype = CPU_UNKNOWN;
+	}
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		mips_cpu.fpu_id = cpu_get_fpu_id();
+}
+
+__init 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);
+}
diff -urN linux-2.4.20-pre6/arch/mips/kernel/entry.S linux-2.4.20-pre7/arch/mips/kernel/entry.S
--- linux-2.4.20-pre6/arch/mips/kernel/entry.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/entry.S	Thu Sep 12 20:01:40 2002
@@ -26,48 +26,29 @@
 #include <asm/unistd.h>
 #include <asm/isadep.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002		/* tracing system calls */
-
 
 		.text
 		.align 4
 		.set	push
 		.set	reorder
-EXPORT(ret_from_fork)
-		move	a0, v0			# prev
-		jal	schedule_tail
-		lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-		andi	t0, PT_TRACESYS
-		bnez	t0, tracesys_exit
-		j	ret_from_sys_call
-
-tracesys_exit:	jal	syscall_trace
-		b	ret_from_sys_call
-
-EXPORT(ret_from_irq)
-EXPORT(ret_from_exception)
+FEXPORT(ret_from_irq)
+FEXPORT(ret_from_exception)
 		lw	t0, PT_STATUS(sp)	# returning to kernel mode?
 		andi	t0, t0, KU_USER
-		bnez	t0, ret_from_sys_call
-		j	restore_all
-
-reschedule:	jal	schedule 
-
-EXPORT(ret_from_sys_call)
-		.type	ret_from_irq,@function
+		beqz	t0, restore_all
 
+FEXPORT(ret_from_sys_call)		# here to prevent code duplication
+ret_from_schedule:
 		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
 		ori	t0, t0, 1
 		xori	t0, t0, 1
 		mtc0	t0, CP0_STATUS
-		nop; nop; nop
+		SSNOP; SSNOP; SSNOP
 
 		lw	v0, TASK_NEED_RESCHED($28)
 		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
@@ -85,6 +66,10 @@
 		jal	do_signal
 		b	restore_all
 
+reschedule:
+		jal	schedule
+		b	ret_from_schedule
+
 /*
  * Common spurious interrupt handler.
  */
@@ -100,35 +85,38 @@
 		addiu   t0,1
 		sw      t0,%lo(irq_err_count)(t1)
 		j	ret_from_irq
-		END(spurious_interrupt)
+END(spurious_interrupt)
 
 		__INIT
 
 		.set	reorder
 
-		NESTED(except_vec1_generic, 0, sp)
+NESTED(except_vec1_generic, 0, sp)
 		PANIC("Exception vector 1 called")
-		END(except_vec1_generic)
+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)
+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)
+END(except_vec3_generic)
 		.set	at
 
 		/* General exception vector R4000 version. */
-		NESTED(except_vec3_r4000, 0, sp)
+NESTED(except_vec3_r4000, 0, sp)
 		.set	push
 		.set    mips3
 		.set	noat
+#if defined(R5432_CP0_INTERRUPT_WAR)
+		mfc0	k0, CP0_INDEX
+#endif
 		mfc0	k1, CP0_CAUSE
 		li	k0, 31<<2
 		andi	k1, k1, 0x7c
@@ -174,7 +162,7 @@
 #endif
 		eret
 		.set    pop
-		END(except_vec3_r4000)
+END(except_vec3_r4000)
 
 		__FINIT
 
@@ -221,10 +209,10 @@
 		.previous;
 #define BUILD_HANDLER(exception,handler,clear,verbose)                  \
 		.align	5;                                              \
-		NESTED(handle_##exception, PT_SIZE, sp);                \
+NESTED(handle_##exception, PT_SIZE, sp);		                \
 		.set	noat;                                           \
 		SAVE_ALL;                                               \
-		FEXPORT(handle_##exception##_int);			\
+FEXPORT(handle_##exception##_int);					\
 		__BUILD_clear_##clear(exception);                       \
 		.set	at;                                             \
 		__BUILD_##verbose(exception);                           \
@@ -232,7 +220,7 @@
 		 move	a0, sp;                                         \
 		j	ret_from_exception;                             \
 		 nop;                                                   \
-		END(handle_##exception)
+END(handle_##exception)
 
 		BUILD_HANDLER(adel,ade,ade,silent)		/* #4  */
 		BUILD_HANDLER(ades,ade,ade,silent)		/* #5  */
diff -urN linux-2.4.20-pre6/arch/mips/kernel/gdb-low.S linux-2.4.20-pre7/arch/mips/kernel/gdb-low.S
--- linux-2.4.20-pre6/arch/mips/kernel/gdb-low.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/gdb-low.S	Thu Sep 12 20:01:40 2002
@@ -97,7 +97,7 @@
 		sw	ra,GDB_FR_REG31(sp)
 
 		CLI				/* disable interrupts */
-		
+
 /*
  * Followed by the floating point registers
  */
@@ -211,7 +211,7 @@
 		lw	v0,GDB_FR_CP0_CONTEXT(sp)
 		mtc0	v1,CP0_INDEX
 		mtc0	v0,CP0_CONTEXT
-		
+
 
 /*
  * Next, the floating point registers
diff -urN linux-2.4.20-pre6/arch/mips/kernel/gdb-stub.c linux-2.4.20-pre7/arch/mips/kernel/gdb-stub.c
--- linux-2.4.20-pre6/arch/mips/kernel/gdb-stub.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/gdb-stub.c	Thu Sep 12 20:01:40 2002
@@ -62,7 +62,7 @@
  * Host:                  Reply:
  * $m0,10#2a               +$00010203040506070809101112131415#42
  *
- * 
+ *
  *  ==============
  *  MORE EXAMPLES:
  *  ==============
@@ -72,11 +72,11 @@
  *  going. In this scenario the host machine was a PC and the
  *  target platform was a Galileo EVB64120A MIPS evaluation
  *  board.
- *   
+ *
  *  Step 1:
  *  First download gdb-5.0.tar.gz from the internet.
  *  and then build/install the package.
- * 
+ *
  *  Example:
  *    $ tar zxf gdb-5.0.tar.gz
  *    $ cd gdb-5.0
@@ -85,35 +85,35 @@
  *    $ install
  *    $ which mips-linux-elf-gdb
  *    /usr/local/bin/mips-linux-elf-gdb
- * 
+ *
  *  Step 2:
  *  Configure linux for remote debugging and build it.
- * 
+ *
  *  Example:
  *    $ cd ~/linux
  *    $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
  *    $ make dep; make vmlinux
- * 
+ *
  *  Step 3:
  *  Download the kernel to the remote target and start
- *  the kernel running. It will promptly halt and wait 
+ *  the kernel running. It will promptly halt and wait
  *  for the host gdb session to connect. It does this
- *  since the "Kernel Hacking" option has defined 
+ *  since the "Kernel Hacking" option has defined
  *  CONFIG_REMOTE_DEBUG which in turn enables your calls
  *  to:
  *     set_debug_traps();
  *     breakpoint();
- * 
+ *
  *  Step 4:
  *  Start the gdb session on the host.
- * 
+ *
  *  Example:
  *    $ mips-linux-elf-gdb vmlinux
  *    (gdb) set remotebaud 115200
  *    (gdb) target remote /dev/ttyS1
- *    ...at this point you are connected to 
+ *    ...at this point you are connected to
  *       the remote target and can use gdb
- *       in the normal fasion. Setting 
+ *       in the normal fasion. Setting
  *       breakpoints, single stepping,
  *       printing variables, etc.
  *
@@ -213,7 +213,7 @@
 		checksum = 0;
 		xmitcsum = -1;
 		count = 0;
-	
+
 		/*
 		 * now, read until a # or end of buffer is found
 		 */
@@ -378,7 +378,7 @@
 	save_and_cli(flags);
 	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
 		saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low);
-  
+
 	putDebugChar('+'); /* 'hello world' */
 	/*
 	 * In case GDB is started before us, ack any packets
@@ -547,7 +547,7 @@
 		targ += 4 + (insn.i_format.simmediate << 2);
 		break;
 	}
-				
+
 	if (is_branch) {
 		i = 0;
 		if (is_cond && targ != (regs->cp0_epc + 8)) {
@@ -567,7 +567,7 @@
 
 /*
  *  If asynchronously interrupted by gdb, then we need to set a breakpoint
- *  at the interrupted instruction so that we wind up stopped with a 
+ *  at the interrupted instruction so that we wind up stopped with a
  *  reasonable stack frame.
  */
 static struct gdb_bp_save async_bp;
@@ -595,11 +595,11 @@
 	char *ptr;
 	unsigned long *stack;
 
-#if 0	
+#if 0
 	printk("in handle_exception()\n");
 	show_gdbregs(regs);
 #endif
-	
+
 	/*
 	 * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1,
 	 * the simply switch the FPU on and return since this is no error
@@ -619,7 +619,7 @@
 	/*
 	 * If we're in breakpoint() increment the PC
 	 */
-	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)		
+	if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)
 		regs->cp0_epc += 4;
 
 	/*
@@ -629,7 +629,7 @@
 	if (step_bp[0].addr) {
 		*(unsigned *)step_bp[0].addr = step_bp[0].val;
 		step_bp[0].addr = 0;
-		    
+
 		if (step_bp[1].addr) {
 			*(unsigned *)step_bp[1].addr = step_bp[1].val;
 			step_bp[1].addr = 0;
@@ -723,7 +723,7 @@
 			ptr = mem2hex((char *)&regs->frame_ptr, ptr, 2*4, 0); /* frp */
 			ptr = mem2hex((char *)&regs->cp0_index, ptr, 16*4, 0); /* cp0 */
 			break;
-	  
+
 		/*
 		 * set the value of the CPU registers - return OK
 		 * FIXME: Needs to be written
@@ -769,7 +769,7 @@
 		/*
 		 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
 		 */
-		case 'M': 
+		case 'M':
 			ptr = &input_buffer[1];
 
 			if (hexToInt(&ptr, &addr)
@@ -788,13 +788,13 @@
 		/*
 		 * cAA..AA    Continue at address AA..AA(optional)
 		 */
-		case 'c':    
+		case 'c':
 			/* try to read optional parameter, pc unchanged if no parm */
 
 			ptr = &input_buffer[1];
 			if (hexToInt(&ptr, &addr))
 				regs->cp0_epc = addr;
-	  
+
 			/*
 			 * Need to flush the instruction cache here, as we may
 			 * have deposited a breakpoint, and the icache probably
@@ -843,7 +843,7 @@
 		 */
 		case 'b':
 		{
-#if 0				
+#if 0
 			int baudrate;
 			extern void set_timer_3();
 
@@ -934,7 +934,7 @@
 		int i = (l>8)?8:l;
 		mem2hex((char *)str, &outbuf[1], i, 0);
 		outbuf[(i*2)+1]=0;
-		putpacket(outbuf); 
+		putpacket(outbuf);
 		str += i;
 		l -= i;
 	}
@@ -962,5 +962,5 @@
 {
 	register_console(&gdb_console);
 }
-     
+
 #endif
diff -urN linux-2.4.20-pre6/arch/mips/kernel/head.S linux-2.4.20-pre7/arch/mips/kernel/head.S
--- linux-2.4.20-pre6/arch/mips/kernel/head.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/head.S	Thu Sep 12 20:01:40 2002
@@ -35,6 +35,10 @@
 		 */
 		.fill	0x400
 
+		/* The following two symbols are used for kernel profiling. */
+		EXPORT(stext)
+		EXPORT(_stext)
+
 		__INIT
 
 		/* Cache Error */
@@ -81,7 +85,7 @@
 		 * 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
@@ -94,7 +98,7 @@
 		.set	noat
 		.set	noreorder
 		mtc0	k0, CP0_DESAVE
-		mfc0	k0, CP0_DEBUG	
+		mfc0	k0, CP0_DEBUG
 
 		sll	k0, k0, 30	# Check for SDBBP.
 		bgez	k0, ejtag_return
@@ -106,15 +110,15 @@
 		 move	a0, sp
 		RESTORE_ALL
 		la	k0, ejtag_debug_buffer
-		lw	k1, 0(k0)	
+		lw	k1, 0(k0)
 
 ejtag_return:
-		mfc0	k0, CP0_DESAVE	
+		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
@@ -137,16 +141,13 @@
 		eret
 		.set    at
 		.set    mips0
-		END(nmi_handler)	
+		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
@@ -178,7 +179,7 @@
 
 /*
  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
- * function after setting up the stack and gp registers. 
+ * function after setting up the stack and gp registers.
  */
 		LEAF(smp_bootstrap)
 		.set push
@@ -198,13 +199,13 @@
 		__FINIT
 
 		/*
-		 * This buffer is reserved for the use of the EJTAG debug 
+		 * This buffer is reserved for the use of the EJTAG debug
 		 * handler.
 		 */
 		.data
 		EXPORT(ejtag_debug_buffer)
 		.fill	4
-	
+
 		.comm	kernelsp,    NR_CPUS * 8, 8
 		.comm	pgd_current, NR_CPUS * 8, 8
 
diff -urN linux-2.4.20-pre6/arch/mips/kernel/i8259.c linux-2.4.20-pre7/arch/mips/kernel/i8259.c
--- linux-2.4.20-pre6/arch/mips/kernel/i8259.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/i8259.c	Thu Sep 12 20:01:40 2002
@@ -42,7 +42,7 @@
 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 */
diff -urN linux-2.4.20-pre6/arch/mips/kernel/ipc.c linux-2.4.20-pre7/arch/mips/kernel/ipc.c
--- linux-2.4.20-pre6/arch/mips/kernel/ipc.c	Thu Feb 24 22:52:30 2000
+++ linux-2.4.20-pre7/arch/mips/kernel/ipc.c	Thu Sep 12 20:01:40 2002
@@ -45,7 +45,7 @@
 	}
 
 	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+		return sys_msgsnd (first, (struct msgbuf *) ptr,
 				   second, third);
 	case MSGRCV:
 		switch (version) {
@@ -53,9 +53,9 @@
 			struct ipc_kludge tmp;
 			if (!ptr)
 				return -EINVAL;
-			
+
 			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr, 
+					   (struct ipc_kludge *) ptr,
 					   sizeof (tmp)))
 				return -EFAULT;
 			return sys_msgrcv (first, tmp.msgp, second,
@@ -85,7 +85,7 @@
 				return -EINVAL;
 			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 		}
-	case SHMDT: 
+	case SHMDT:
 		return sys_shmdt ((char *)ptr);
 	case SHMGET:
 		return sys_shmget (first, second, third);
diff -urN linux-2.4.20-pre6/arch/mips/kernel/irixelf.c linux-2.4.20-pre7/arch/mips/kernel/irixelf.c
--- linux-2.4.20-pre6/arch/mips/kernel/irixelf.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/irixelf.c	Thu Sep 12 20:01:40 2002
@@ -128,7 +128,7 @@
 {
 	start = PAGE_ALIGN(start);
 	end = PAGE_ALIGN(end);
-	if (end <= start) 
+	if (end <= start)
 		return;
 	do_brk(start, end - start);
 }
@@ -158,7 +158,7 @@
 	elf_caddr_t *argv;
 	elf_caddr_t *envp;
 	elf_addr_t *sp, *csp;
-	
+
 #ifdef DEBUG_ELF
 	printk("create_irix_tables: p[%p] argc[%d] envc[%d] "
 	       "load_addr[%08x] interp_load_addr[%08x]\n",
@@ -247,7 +247,7 @@
 	elf_bss = 0;
 	last_bss = 0;
 	error = load_addr = 0;
-	
+
 #ifdef DEBUG_ELF
 	print_elfhdr(interp_elf_ex);
 #endif
@@ -268,7 +268,7 @@
 	    return 0xffffffff;
 	}
 
-	elf_phdata =  (struct elf_phdr *) 
+	elf_phdata =  (struct elf_phdr *)
 		kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,
 			GFP_KERNEL);
 
@@ -394,7 +394,7 @@
 		return -ENOEXEC;
 
 	/* First of all, some simple consistency checks */
-	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || 
+	if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
 	    !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) {
 		return -ENOEXEC;
 	}
@@ -558,7 +558,7 @@
 }
 
 /*
- * IRIX maps a page at 0x200000 that holds information about the 
+ * IRIX maps a page at 0x200000 that holds information about the
  * process and the system, here we map the page and fill the
  * structure
  */
@@ -568,7 +568,7 @@
 	struct prda *pp;
 
 	v =  do_brk (PRDA_ADDRESS, PAGE_SIZE);
-	
+
 	if (v < 0)
 		return;
 
@@ -579,9 +579,9 @@
 
 	/* We leave the rest set to zero */
 }
-	
 
-	
+
+
 /* These are the functions used to load ELF style executables and shared
  * libraries.  There is no binary dependent code anywhere else.
  */
@@ -596,7 +596,7 @@
 	int retval, has_interp, has_ephdr, size, i;
 	char *elf_interpreter;
 	mm_segment_t old_fs;
-	
+
 	load_addr = 0;
 	has_interp = has_ephdr = 0;
 	elf_ihdr = elf_ephdr = 0;
@@ -685,7 +685,7 @@
 	current->mm->mmap = NULL;
 	current->flags &= ~PF_FORKNOEXEC;
 	elf_entry = (unsigned int) elf_ex.e_entry;
-	
+
 	/* Do this so that we can load the interpreter, if need be.  We will
 	 * change some of these later.
 	 */
@@ -724,7 +724,7 @@
 	set_binfmt(&irix_format);
 	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
-	bprm->p = (unsigned long) 
+	bprm->p = (unsigned long)
 	  create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc,
 			(elf_interpreter ? &elf_ex : NULL),
 			load_addr, interp_load_addr, regs, elf_ephdr);
@@ -812,30 +812,30 @@
 	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
 	   !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap)
 		return -ENOEXEC;
-	
+
 	/* Now read in all of the header information. */
 	if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)
 		return -ENOEXEC;
-	
-	elf_phdata =  (struct elf_phdr *) 
+
+	elf_phdata =  (struct elf_phdr *)
 		kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
 	if (elf_phdata == NULL)
 		return -ENOMEM;
-	
+
 	retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata,
 			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
-	
+
 	j = 0;
 	for(i=0; i<elf_ex.e_phnum; i++)
 		if((elf_phdata + i)->p_type == PT_LOAD) j++;
-	
+
 	if(j != 1)  {
 		kfree(elf_phdata);
 		return -ENOEXEC;
 	}
-	
+
 	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
-	
+
 	/* Now use mmap to map the library into memory. */
 	down_write(&current->mm->mmap_sem);
 	error = do_mmap(file,
@@ -863,7 +863,7 @@
 	kfree(elf_phdata);
 	return 0;
 }
-	
+
 /* Called through irix_syssgi() to map an elf image given an FD,
  * a phdr ptr USER_PHDRP in userspace, and a count CNT telling how many
  * phdrs there are in the USER_PHDRP array.  We return the vaddr the
@@ -1026,7 +1026,7 @@
 	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
 	DUMP_WRITE(men->data, men->datasz);
 	DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));	/* XXX */
-	
+
 	return 1;
 
 end_coredump:
@@ -1072,13 +1072,13 @@
 		if (maydump(vma))
 		{
 			int sz = vma->vm_end-vma->vm_start;
-		
+
 			if (size+sz >= limit)
 				break;
 			else
 				size += sz;
 		}
-		
+
 		segs++;
 	}
 #ifdef DEBUG
@@ -1105,7 +1105,7 @@
 	elf.e_shentsize = 0;
 	elf.e_shnum = 0;
 	elf.e_shstrndx = 0;
-	
+
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
@@ -1147,7 +1147,7 @@
 	} else {
 		*(struct pt_regs *)&prstatus.pr_reg = *regs;
 	}
-	
+
 	notes[1].name = "CORE";
 	notes[1].type = NT_PRPSINFO;
 	notes[1].datasz = sizeof(psinfo);
@@ -1164,7 +1164,7 @@
 		int i, len;
 
 		set_fs(fs);
-		
+
 		len = current->mm->arg_end - current->mm->arg_start;
 		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
 		copy_from_user(&psinfo.pr_psargs,
@@ -1201,7 +1201,7 @@
 
 		for(i = 0; i < numnote; i++)
 			sz += notesize(&notes[i]);
-		
+
 		phdr.p_type = PT_NOTE;
 		phdr.p_offset = offset;
 		phdr.p_vaddr = 0;
@@ -1217,7 +1217,7 @@
 
 	/* Page-align dumped data. */
 	dataoff = offset = roundup(offset, PAGE_SIZE);
-	
+
 	/* Write program headers for segments dump. */
 	for(vma = current->mm->mmap, i = 0;
 		i < segs && vma != NULL; vma = vma->vm_next) {
@@ -1227,7 +1227,7 @@
 		i++;
 
 		sz = vma->vm_end - vma->vm_start;
-		
+
 		phdr.p_type = PT_LOAD;
 		phdr.p_offset = offset;
 		phdr.p_vaddr = vma->vm_start;
@@ -1246,17 +1246,17 @@
 	for(i = 0; i < numnote; i++)
 		if (!writenote(&notes[i], file))
 			goto end_coredump;
-	
+
 	set_fs(fs);
 
 	DUMP_SEEK(dataoff);
-	
+
 	for(i = 0, vma = current->mm->mmap;
 	    i < segs && vma != NULL;
 	    vma = vma->vm_next) {
 		unsigned long addr = vma->vm_start;
 		unsigned long len = vma->vm_end - vma->vm_start;
-		
+
 		if (!maydump(vma))
 			continue;
 		i++;
diff -urN linux-2.4.20-pre6/arch/mips/kernel/irixinv.c linux-2.4.20-pre7/arch/mips/kernel/irixinv.c
--- linux-2.4.20-pre6/arch/mips/kernel/irixinv.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/irixinv.c	Thu Sep 12 20:01:40 2002
@@ -1,7 +1,7 @@
 /*
  * Support the inventory interface for IRIX binaries
  * This is invoked before the mm layer is working, so we do not
- * use the linked lists for the inventory yet. 
+ * use the linked lists for the inventory yet.
  *
  * Miguel de Icaza, 1997.
  */
@@ -23,7 +23,7 @@
 
 	if (inventory_items == MAX_INVENTORY)
 		return;
-	
+
 	ni->inv_class      = class;
 	ni->inv_type       = type;
 	ni->inv_controller = controller;
@@ -57,7 +57,7 @@
 	 * most likely this will not let just anyone run the X server
 	 * until we put the right values all over the place
 	 */
-	 
+
 	add_to_inventory (10, 3, 0, 0, 16400);
 	add_to_inventory (1, 1, 150, -1, 12);
 	add_to_inventory (1, 3, 0, 0, 8976);
diff -urN linux-2.4.20-pre6/arch/mips/kernel/irixsig.c linux-2.4.20-pre7/arch/mips/kernel/irixsig.c
--- linux-2.4.20-pre6/arch/mips/kernel/irixsig.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips/kernel/irixsig.c	Thu Sep 12 20:01:40 2002
@@ -379,7 +379,7 @@
 }
 #endif
 
-asmlinkage int 
+asmlinkage int
 irix_sigaction(int sig, const struct sigaction *act,
 	      struct sigaction *oact, void *trampoline)
 {
diff -urN linux-2.4.20-pre6/arch/mips/kernel/irq.c linux-2.4.20-pre7/arch/mips/kernel/irq.c
--- linux-2.4.20-pre6/arch/mips/kernel/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/irq.c	Thu Sep 12 20:01:40 2002
@@ -31,6 +31,8 @@
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
+static void register_irq_proc (unsigned int irq);
+
 /*
  * Special irq handlers.
  */
@@ -48,7 +50,7 @@
 {
 	/*
 	 * '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
+	 * each architecture has to answer this themselves, it doesn't deserve
 	 * a generic callback i think.
 	 */
 	printk("unexpected interrupt %d\n", irq);
@@ -87,7 +89,7 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_desc[i].action;
-		if (!action) 
+		if (!action)
 			continue;
 		p += sprintf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
@@ -198,12 +200,12 @@
 }
 
 /*
- * A global "cli()" while in an interrupt context turns into just a local 
- * cli(). Interrupts should use spinlocks for the (very unlikely) case that 
+ * 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 
+ *
+ * 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).
  */
 
@@ -317,9 +319,9 @@
  * 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. 
+ * controller lock.
  */
- 
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -330,7 +332,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void inline disable_irq_nosync(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -356,7 +358,7 @@
  *
  *	This function may be called - with care - from IRQ context.
  */
- 
+
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
@@ -377,7 +379,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void enable_irq(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -412,7 +414,7 @@
  */
 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
@@ -472,7 +474,7 @@
 		spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, regs, action);
 		spin_lock(&desc->lock);
-		
+
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -502,7 +504,7 @@
  *	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 
+ *	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.
  *
@@ -522,10 +524,10 @@
  *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
  *
  */
- 
-int request_irq(unsigned int irq, 
+
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
@@ -580,12 +582,12 @@
  *	does not return until any executing interrupts for this IRQ
  *	have completed.
  *
- *	This function may be called from interrupt context. 
+ *	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;
@@ -646,7 +648,7 @@
  *	and a mask of potential interrupt lines is returned.
  *
  */
- 
+
 unsigned long probe_irq_on(void)
 {
 	unsigned int i;
@@ -655,15 +657,15 @@
 	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. 
+	 * 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) 
+		if (!irq_desc[i].action)
 			irq_desc[i].handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
@@ -725,7 +727,7 @@
  * 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
@@ -787,7 +789,7 @@
  *	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;
diff -urN linux-2.4.20-pre6/arch/mips/kernel/irq_cpu.c linux-2.4.20-pre7/arch/mips/kernel/irq_cpu.c
--- linux-2.4.20-pre6/arch/mips/kernel/irq_cpu.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/irq_cpu.c	Thu Sep 12 20:01:40 2002
@@ -13,7 +13,7 @@
 /*
  * 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 
+ * 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.
  *
diff -urN linux-2.4.20-pre6/arch/mips/kernel/mips_ksyms.c linux-2.4.20-pre7/arch/mips/kernel/mips_ksyms.c
--- linux-2.4.20-pre6/arch/mips/kernel/mips_ksyms.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/mips_ksyms.c	Thu Sep 12 20:01:40 2002
@@ -43,7 +43,9 @@
 extern long __strnlen_user_asm(const char *s);
 
 EXPORT_SYMBOL(mips_machtype);
+#ifdef CONFIG_EISA
 EXPORT_SYMBOL(EISA_bus);
+#endif
 
 /*
  * String functions
diff -urN linux-2.4.20-pre6/arch/mips/kernel/old-irq.c linux-2.4.20-pre7/arch/mips/kernel/old-irq.c
--- linux-2.4.20-pre6/arch/mips/kernel/old-irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/old-irq.c	Thu Sep 12 20:01:40 2002
@@ -130,7 +130,7 @@
 
 	for (i = 0 ; i < 32 ; i++) {
 		action = irq_action[i];
-		if (!action) 
+		if (!action)
 			continue;
 		len += sprintf(buf+len, "%2d: %8d %c %s",
 			i, kstat.irqs[0][i],
@@ -286,7 +286,7 @@
  * specific variants.  For now we still use this as broken as it is because
  * it used to work ...
  */
-int request_irq(unsigned int irq, 
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
 		unsigned long irqflags, const char * devname, void *dev_id)
 {
@@ -315,7 +315,7 @@
 		kfree(action);
 	return retval;
 }
-		
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	struct irqaction * action, **p;
@@ -386,7 +386,7 @@
 	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 */
diff -urN linux-2.4.20-pre6/arch/mips/kernel/old-time.c linux-2.4.20-pre7/arch/mips/kernel/old-time.c
--- linux-2.4.20-pre6/arch/mips/kernel/old-time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/old-time.c	Thu Sep 12 20:01:40 2002
@@ -106,7 +106,7 @@
 		 "r" (quotient));
 
 	/*
- 	 * Due to possible jiffies inconsistencies, we need to check 
+ 	 * 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)
@@ -115,9 +115,9 @@
 	return res;
 }
 
-/* This function must be called with interrupts disabled 
+/* This function must be called with interrupts disabled
  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
- * 
+ *
  * However, the pc-audio speaker driver changes the divisor so that
  * it gets interrupted rather more often - it loads 64 into the
  * counter rather than 11932! This has an adverse impact on
@@ -131,7 +131,7 @@
  * using either the RTC or the 8253 timer. The decision would be
  * based on whether there was any other device around that needed
  * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
- * and then do some jiggery to have a version of do_timer that 
+ * and then do some jiggery to have a version of do_timer that
  * advanced the clock by 1/1024 s. Every time that reached over 1/100
  * of a second, then do all the old code. If the time was kept correct
  * then do_gettimeoffset could just return 0 - there is no low order
@@ -142,7 +142,7 @@
  * often than every 120 us or so.
  *
  * Anyway, this needs more thought....		pjsg (1993-08-28)
- * 
+ *
  * If you are really that interested, you should be reading
  * comp.protocols.time.ntp!
  */
@@ -157,7 +157,7 @@
 	static unsigned long jiffies_p;
 
 	/*
-	 * cache volatile jiffies temporarily; we have IRQs turned off. 
+	 * cache volatile jiffies temporarily; we have IRQs turned off.
 	 */
 	unsigned long jiffies_t;
 
@@ -167,7 +167,7 @@
 	count = inb_p(0x40);	/* read the latched count */
 
 	/*
-	 * We do this guaranteed double memory access instead of a _p 
+	 * We do this guaranteed double memory access instead of a _p
 	 * postfix in the previous port access. Wheee, hackady hack
 	 */
 	jiffies_t = jiffies;
@@ -192,7 +192,7 @@
 			/* assumption about timer being IRQ1 */
 			if (inb(0x20) & 0x01) {
 				/*
-				 * We cannot detect lost timer interrupts ... 
+				 * We cannot detect lost timer interrupts ...
 				 * well, that's why we call them lost, don't we? :)
 				 * [hmm, on the Pentium and Alpha we can ... sort of]
 				 */
@@ -348,7 +348,7 @@
 	    ddb5074_led_d2(1);
 	else if (cnt == 7 || cnt == dist+7)
 	    ddb5074_led_d2(0);
-	
+
 	if (++cnt > period) {
 	    cnt = 0;
 	    /* The hyperbolic function below modifies the heartbeat period
@@ -383,7 +383,7 @@
 	 * 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.
 	 */
-	read_lock (&xtime_lock); 
+	read_lock (&xtime_lock);
 	if ((time_status & STA_UNSYNC) == 0 &&
 	    xtime.tv_sec > last_rtc_update + 660 &&
 	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
@@ -402,10 +402,10 @@
 	 * look closely for now..
 	 */
 	/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
-	read_unlock (&xtime_lock); 
+	read_unlock (&xtime_lock);
 }
 
-static inline void 
+static inline void
 r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	unsigned int count;
@@ -425,7 +425,7 @@
 	 * we need only ask for the next in r4k_interval counts. On other
 	 * archs we have a real timer, so we don't want this.
 	 */
-	write_32bit_cp0_register (CP0_COMPARE, 
+	write_32bit_cp0_register (CP0_COMPARE,
 				  (unsigned long) (count + r4k_interval));
         kstat.irqs[0][irq]++;
 #endif
diff -urN linux-2.4.20-pre6/arch/mips/kernel/pci-dma.c linux-2.4.20-pre7/arch/mips/kernel/pci-dma.c
--- linux-2.4.20-pre6/arch/mips/kernel/pci-dma.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/pci-dma.c	Thu Sep 12 20:01:40 2002
@@ -22,17 +22,19 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
+#ifdef CONFIG_ISA
 	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
+#endif
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
 		memset(ret, 0, size);
+		*dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret));
 #ifdef CONFIG_NONCOHERENT_IO
 		dma_cache_wback_inv((unsigned long) ret, size);
-		ret = KSEG1ADDR(ret);
+		ret = UNCAC_ADDR(ret);
 #endif
-		*dma_handle = virt_to_bus(ret);
 	}
 
 	return ret;
@@ -44,7 +46,7 @@
 	unsigned long addr = (unsigned long) vaddr;
 
 #ifdef CONFIG_NONCOHERENT_IO
-	addr = KSEG0ADDR(addr);
+	addr = CAC_ADDR(addr);
 #endif
 	free_pages(addr, get_order(size));
 }
diff -urN linux-2.4.20-pre6/arch/mips/kernel/pci_auto.c linux-2.4.20-pre7/arch/mips/kernel/pci_auto.c
--- linux-2.4.20-pre6/arch/mips/kernel/pci_auto.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/pci_auto.c	Thu Sep 12 20:01:40 2002
@@ -42,7 +42,7 @@
 #ifdef 	DEBUG
 #define	DBG(x...)	printk(x)
 #else
-#define	DBG(x...)	
+#define	DBG(x...)
 #endif
 
 /*
@@ -95,7 +95,7 @@
 static u32 pciauto_lower_memspc;
 static u32 pciauto_upper_memspc;
 
-void __init 
+void __init
 pciauto_setup_bars(struct pci_channel *hose,
 		   int top_bus,
 		   int current_bus,
@@ -144,7 +144,7 @@
 			    PCI_BASE_ADDRESS_MEM_TYPE_64)
 				found_mem64 = 1;
 
-			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
 			upper_limit = &pciauto_upper_memspc;
 			lower_limit = &pciauto_lower_memspc;
 			DBG("        Mem");
@@ -160,22 +160,22 @@
 		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 =
 						io_resource_inuse->child;
-					pciauto_lower_iospc = 
+					pciauto_lower_iospc =
 						io_resource_inuse->start;
-					pciauto_upper_iospc = 
+					pciauto_upper_iospc =
 						io_resource_inuse->end + 1;
 					goto retry;
 				}
 
 			} else {
 				if (mem_resource_inuse->child) {
-					mem_resource_inuse = 
+					mem_resource_inuse =
 						mem_resource_inuse->child;
-					pciauto_lower_memspc = 
+					pciauto_lower_memspc =
 						mem_resource_inuse->start;
-					pciauto_upper_memspc = 
+					pciauto_upper_memspc =
 						mem_resource_inuse->end + 1;
 					goto retry;
 				}
@@ -194,7 +194,7 @@
 		 * 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, top_bus,
@@ -295,12 +295,12 @@
 	int devfn_stop = 0xff;
 
 	sub_bus = current_bus;
-	
+
 	if (hose->first_devfn)
 		devfn_start = hose->first_devfn;
 	if (hose->last_devfn)
 		devfn_stop = hose->last_devfn;
-	
+
 	for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
 
 		if (PCI_FUNC(pci_devfn) && !found_multi)
@@ -387,7 +387,7 @@
 	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, 
+		busno, pciauto_lower_iospc, pciauto_upper_iospc,
 		pciauto_lower_memspc, pciauto_upper_memspc);
 
 	return pciauto_bus_scan(hose, busno, busno);
diff -urN linux-2.4.20-pre6/arch/mips/kernel/proc.c linux-2.4.20-pre7/arch/mips/kernel/proc.c
--- linux-2.4.20-pre6/arch/mips/kernel/proc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/proc.c	Thu Sep 12 20:01:40 2002
@@ -67,7 +67,13 @@
 	[CPU_R5500]	"R5500",
 	[CPU_TX49XX]	"TX49xx",
 	[CPU_TX39XX]	"TX39xx",
-	[CPU_20KC]	"MIPS 20Kc"
+	[CPU_20KC]	"MIPS 20Kc",
+	[CPU_VR4111]	"NEC VR4111",
+	[CPU_VR4121]	"NEC VR4121",
+	[CPU_VR4122]	"NEC VR4122",
+	[CPU_VR4131]	"NEC VR4131",
+	[CPU_VR4181]	"NEC VR4181",
+	[CPU_VR4181A]	"NEC VR4181A"
 };
 
 
diff -urN linux-2.4.20-pre6/arch/mips/kernel/process.c linux-2.4.20-pre7/arch/mips/kernel/process.c
--- linux-2.4.20-pre6/arch/mips/kernel/process.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/process.c	Thu Sep 12 20:01:40 2002
@@ -77,7 +77,6 @@
 {
 	struct pt_regs * childregs;
 	long childksp;
-	extern void save_fp(void*);
 
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
 
diff -urN linux-2.4.20-pre6/arch/mips/kernel/ptrace.c linux-2.4.20-pre7/arch/mips/kernel/ptrace.c
--- linux-2.4.20-pre6/arch/mips/kernel/ptrace.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/ptrace.c	Thu Sep 12 20:01:40 2002
@@ -84,7 +84,7 @@
 		goto out_tsk;
 
 	switch (request) {
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned long tmp;
 		int copied;
@@ -119,7 +119,7 @@
 			 	if(!(mips_cpu.options & MIPS_CPU_FPU)) {
 					fregs = (unsigned long long *)
 						child->thread.fpu.soft.regs;
-				} else 
+				} else
 					if (last_task_used_math == child) {
 						__enable_fpu();
 						save_fp(child);
@@ -132,11 +132,6 @@
 				 * order bits of the values stored in the even
 				 * registers - unless we're using r2k_switch.S.
 				 */
-#ifdef CONFIG_CPU_R3000
-				if (mips_cpu.options & MIPS_CPU_FPU)
-					tmp = *(unsigned long *)(fregs + addr);
-				else
-#endif
 				if (addr & 1)
 					tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
 				else
@@ -258,7 +253,7 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			if (!(mips_cpu.options & MIPS_CPU_FPU)) 
+			if (!(mips_cpu.options & MIPS_CPU_FPU))
 				child->thread.fpu.soft.sr = data;
 			else
 				child->thread.fpu.hard.control = data;
@@ -287,8 +282,8 @@
 		}
 
 	/*
-	 * 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 
+	 * 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:
diff -urN linux-2.4.20-pre6/arch/mips/kernel/r4k_switch.S linux-2.4.20-pre7/arch/mips/kernel/r4k_switch.S
--- linux-2.4.20-pre6/arch/mips/kernel/r4k_switch.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/r4k_switch.S	Thu Sep 12 20:01:40 2002
@@ -46,16 +46,16 @@
 	move	$28, a1
 	CPU_RESTORE_NONSCRATCH($28)
 	addiu	t0, $28, KERNEL_STACK_SIZE-32
-#ifdef CONFIG_SMP	 
+#ifdef CONFIG_SMP
 	mfc0	a3, CP0_CONTEXT
 	la	t1, kernelsp
 	srl	a3, 23
 	sll	a3, 2
 	addu	t1, a3, t1
-	sw	t0, (t1)	
+	sw	t0, (t1)
 #else
 	sw	t0, kernelsp
-#endif 
+#endif
 	mfc0	t1, CP0_STATUS		/* Do we really need this? */
 	li	a3, 0xff00
 	and	t1, a3
@@ -80,6 +80,7 @@
 	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
@@ -129,6 +130,7 @@
 	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 
 	li	t1, FPU_DEFAULT
 	ctc1	t1, fcr31
diff -urN linux-2.4.20-pre6/arch/mips/kernel/scall_o32.S linux-2.4.20-pre7/arch/mips/kernel/scall_o32.S
--- linux-2.4.20-pre6/arch/mips/kernel/scall_o32.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/scall_o32.S	Thu Sep 12 20:01:40 2002
@@ -38,7 +38,7 @@
 	sll	t0, v0, 2
 	lw	t2, sys_call_table(t0)	# syscall routine
 	lbu	t3, sys_narg_table(v0)	# number of arguments
-	beqz	t2, illegal_syscall;
+	beqz	t2, illegal_syscall
 
 	subu	t0, t3, 5		# 5 or more arguments?
 	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
@@ -47,7 +47,7 @@
 stack_done:
         sw      a3, PT_R26(sp)          # save for syscall restart
 	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
+	andi	t0, _PT_TRACESYS
 	bnez	t0, trace_a_syscall
 
 	jalr	t2			# Do The Real Thing (TM)
@@ -61,20 +61,41 @@
 	sw	v0, PT_R0(sp)		# set flag for syscall restarting
 1:	sw	v0, PT_R2(sp)		# result
 
-EXPORT(o32_ret_from_sys_call)
+fast_ret_from_sys_call:
+ret_from_schedule:
 	mfc0	t0, CP0_STATUS		# need_resched and signals atomic test
 	ori	t0, t0, 1
 	xori	t0, t0, 1
 	mtc0	t0, CP0_STATUS
+	SSNOP; SSNOP; SSNOP
 
 	lw	t2, TASK_NEED_RESCHED($28)
-	bnez	t2, o32_reschedule
 	lw	v0, TASK_SIGPENDING($28)
+	bnez	t2, reschedule
 	bnez	v0, signal_return
 restore_all:
 	RESTORE_SOME
 	RESTORE_SP_AND_RET
 
+/* ------------------------------------------------------------------------ */
+
+FEXPORT(ret_from_fork)
+	move	a0, v0			# prev
+	jal	schedule_tail
+	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+	andi	t0, _PT_TRACESYS
+	bnez	t0, tracesys_exit
+
+static_ret_from_sys_call:
+	RESTORE_STATIC
+	j	fast_ret_from_sys_call
+
+/* ------------------------------------------------------------------------ */
+
+/* ret_from_sys_call should be here but is in entry.S.  */
+
+/* ------------------------------------------------------------------------ */
+
 /* Put this behind restore_all for the sake of the branch prediction.  */
 signal_return:
 	.type	signal_return, @function
@@ -87,11 +108,14 @@
 	move	a0, zero
 	move	a1, sp
 	jal	do_signal
+	RESTORE_STATIC
 	b	restore_all
 
-o32_reschedule:
+/* ------------------------------------------------------------------------ */
+
+reschedule:
 	jal	schedule
-	b	o32_ret_from_sys_call
+	b	ret_from_schedule
 
 /* ------------------------------------------------------------------------ */
 
@@ -116,8 +140,9 @@
 	sw	v0, PT_R0(sp)		# set flag for syscall restarting
 1:	sw	v0, PT_R2(sp)		# result
 
+tracesys_exit:
 	jal	syscall_trace
-	j	ret_from_sys_call
+	j	static_ret_from_sys_call
 
 /* ------------------------------------------------------------------------ */
 
@@ -136,7 +161,7 @@
 	bltz	t0, bad_stack		# -> sp is bad
 
 	lw	t0, PT_R29(sp)		# get old user stack pointer
-	la	t1, 3f			# copy 1 to 2 arguments
+	PTR_LA	t1, 3f			# copy 1 to 2 arguments
 	sll	t3, t3, 4
 	subu	t1, t3
 	jr	t1
@@ -150,6 +175,7 @@
 	 */
 	.set    push
 	.set    noreorder
+	.set	nomacro
 1:	lw	t1, 20(t0)		# argument #6 from usp
 	nop
 	sw	t1, 20(sp)
@@ -158,43 +184,58 @@
 	nop
 	sw	t1, 16(sp)
 	nop
-	.set	pop
+3:	.set	pop
 
-3:	j	stack_done		# go back
+	j	stack_done		# go back
 
 	.section __ex_table,"a"
 	PTR	1b,bad_stack
 	PTR	2b,bad_stack
 	.previous
 
+/* ------------------------------------------------------------------------ */
+
 	/*
 	 * The stackpointer for a call with more than 4 arguments is bad.
 	 * We probably should handle this case a bit more drastic.
 	 */
 bad_stack:
-	negu	v0				# error
+	negu	v0			# error
 	sw	v0, PT_R0(sp)
 	sw	v0, PT_R2(sp)
-	li	t0, 1				# set error flag
+	li	t0, 1			# set error flag
 	sw	t0, PT_R7(sp)
-	j	ret_from_sys_call
+	j	fast_ret_from_sys_call
+
+/* ------------------------------------------------------------------------ */
 
 	/*
 	 * The system call does not exist in this kernel
 	 */
 illegal_syscall:
-	li	v0, ENOSYS			# error
+	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+	andi	t0, _PT_TRACESYS
+	beqz	t0, 1f
+
+	SAVE_STATIC
+	jal	syscall_trace
+	li	t0, _PT_TRACESYS
+
+1:	li	v0, ENOSYS		# error
+	sw	v0, PT_R0(sp)		# set flag for syscall restarting
 	sw	v0, PT_R2(sp)
-	li	t0, 1				# set error flag
-	sw	t0, PT_R7(sp)
-	j	ret_from_sys_call
-	END(handle_sys)
+	li	t1, 1			# set error flag
+	sw	t1, PT_R7(sp)
+	bnez	t0, tracesys_exit
 
-	LEAF(mips_atomic_set)
-	andi	v0, a1, 3			# must be word aligned
+	j	fast_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?
+	lw	v1, THREAD_CURDS($28)	# in legal address range?
 	addiu	a0, a1, 4
 	or	a0, a0, a1
 	and	a0, a0, v1
@@ -236,19 +277,17 @@
 	.previous
 #endif
 
+	sw	zero, PT_R7(sp)		# success
 	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
+	andi	t0, _PT_TRACESYS
+	beqz	t0, fast_ret_from_sys_call
 
-1:	SAVE_STATIC
+	SAVE_STATIC
 	jal	syscall_trace
-	li	a3, 0			# success
-	j	ret_from_sys_call
+	j	static_ret_from_sys_call
 
 no_mem:	li	v0, -ENOMEM
 	jr	ra
@@ -260,40 +299,40 @@
 bad_alignment:
 	li	v0, -EINVAL
 	jr	ra
-	END(mips_atomic_set)	
+END(mips_atomic_set)
 
-	LEAF(sys_sysmips)
+LEAF(sys_sysmips)
 	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
 	j	_sys_sysmips
-	END(sys_sysmips)
+END(sys_sysmips)
 
-	LEAF(sys_syscall)
-	lw	t0, PT_R29(sp)			# user sp
+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
+	sll	v0, a0, 2
 	la	v1, sys_syscall
-	lw	t2, sys_call_table(v0)		# function pointer
-	lbu	t4, sys_narg_table(t1)		# number of arguments
+	lw	t2, sys_call_table(v0)	# function pointer
+	lbu	t4, sys_narg_table(a0)	# number of arguments
 
 	li	v0, -EINVAL
-	beq	t2, v1, out			# do not recurse
+	beq	t2, v1, out		# do not recurse
 
-	beqz	t2, enosys			# null function pointer?
+	beqz	t2, enosys		# null function pointer?
 
-	andi	v0, t0, 0x3			# unaligned stack 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
+	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	a0, a1			# shift argument registers
 	move	a1, a2
 	move	a2, a3
 
@@ -307,11 +346,11 @@
 	.word	3b, efault
 	.previous
 
-	sw	t3, 16(sp)			# put into new stackframe
+	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
+	bnez	t4, 1f			# zero arguments?
+	addu	a0, sp, 32		# then pass sp in a0
 1:
 
 	sw	t3, 16(sp)
@@ -331,4 +370,4 @@
 efault:	li	v0, -EFAULT
 
 out:	jr	ra
-	END(sys_syscall)
+END(sys_syscall)
diff -urN linux-2.4.20-pre6/arch/mips/kernel/setup.c linux-2.4.20-pre7/arch/mips/kernel/setup.c
--- linux-2.4.20-pre6/arch/mips/kernel/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/setup.c	Thu Sep 12 20:01:40 2002
@@ -44,22 +44,15 @@
 #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;
-
-/*
  * There are several bus types available for MIPS machines.  "RISC PC"
  * type machines have ISA, EISA, VLB or PCI available, DECstations
  * have Turbochannel or Q-Bus, SGI has GIO, there are lots of VME
  * boxes ...
  * This flag is set if a EISA slots are available.
  */
+#ifdef CONFIG_EISA
 int EISA_bus = 0;
+#endif
 
 struct screen_info screen_info;
 
@@ -122,403 +115,9 @@
 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.
- * 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;
-}
-
-/*
- * 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 = {
-    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;
-
-#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_NOFPUEX;
-			if (cpu_has_fpu())
-				mips_cpu.options |= MIPS_CPU_FPU;
-			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_NOFPUEX;
-			if (cpu_has_fpu())
-				mips_cpu.options |= MIPS_CPU_FPU;
-			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;
-#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;
-			break;
-		default:
-			mips_cpu.cputype = CPU_UNKNOWN;
-			break;
-		}		
-		break;
-	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;
-#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_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
 init_arch(int argc, char **argv, char **envp, int *prom_vec)
 {
-	unsigned int s;
-
 	/* Determine which MIPS variant we are running on. */
 	cpu_probe();
 
@@ -650,10 +249,14 @@
 	void ip22_setup(void);
         void ev96100_setup(void);
 	void malta_setup(void);
+	void sead_setup(void);
 	void ikos_setup(void);
 	void momenco_ocelot_setup(void);
+	void momenco_ocelot_g_setup(void);
 	void nino_setup(void);
 	void nec_osprey_setup(void);
+	void nec_eagle_setup(void);
+	void zao_capcella_setup(void);
 	void jmr3927_setup(void);
  	void it8172_setup(void);
 	void swarm_setup(void);
@@ -679,13 +282,13 @@
 #ifdef CONFIG_PC_KEYB
 	kbd_ops = &no_kbd_ops;
 #endif
-	
+
 	rtc_ops = &no_rtc_ops;
 
 	switch(mips_machgroup)
 	{
 #ifdef CONFIG_BAGET_MIPS
-	case MACH_GROUP_BAGET: 
+	case MACH_GROUP_BAGET:
 		baget_setup();
 		break;
 #endif
@@ -719,6 +322,16 @@
 		momenco_ocelot_setup();
 		break;
 #endif
+#ifdef CONFIG_MOMENCO_OCELOT_G
+	case MACH_GROUP_MOMENCO:
+		momenco_ocelot_g_setup();
+		break;
+#endif
+#ifdef CONFIG_MIPS_SEAD
+	case MACH_GROUP_UNKNOWN:
+		sead_setup();
+		break;
+#endif
 #ifdef CONFIG_SGI_IP22
 	/* As of now this is only IP22.  */
 	case MACH_GROUP_SGI:
@@ -745,9 +358,25 @@
                ddb_setup();
                break;
 #endif
-#ifdef CONFIG_NEC_OSPREY
+#ifdef CONFIG_CPU_VR41XX
 	case MACH_GROUP_NEC_VR41XX:
-		nec_osprey_setup();
+		switch (mips_machtype) {
+#ifdef CONFIG_NEC_OSPREY
+		case MACH_NEC_OSPREY:
+			nec_osprey_setup();
+			break;
+#endif
+#ifdef CONFIG_NEC_EAGLE
+		case MACH_NEC_EAGLE:
+			nec_eagle_setup();
+			break;
+#endif
+#ifdef CONFIG_ZAO_CAPCELLA
+		case MACH_ZAO_CAPCELLA:
+			zao_capcella_setup();
+			break;
+#endif
+		}
 		break;
 #endif
 #ifdef CONFIG_MIPS_EV96100
@@ -765,7 +394,7 @@
 	case  MACH_GROUP_GLOBESPAN:
 		it8172_setup();
 		break;
-#endif  
+#endif
 #ifdef CONFIG_NINO
 	case MACH_GROUP_PHILIPS:
 		nino_setup();
@@ -776,6 +405,11 @@
 		au1000_setup();
 		break;
 #endif
+#ifdef CONFIG_MIPS_PB1100
+	case MACH_GROUP_ALCHEMY:
+		au1100_setup();
+		break;
+#endif
 #ifdef CONFIG_MIPS_PB1500
 	case MACH_GROUP_ALCHEMY:
 		au1500_setup();
@@ -815,8 +449,8 @@
 #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 = (((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) {
@@ -952,17 +586,17 @@
 	}
 	initrd_below_start_ok = 1;
 	if (initrd_start) {
-		unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); 
+		unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start);
 		printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
-		       (void *)initrd_start, 
+		       (void *)initrd_start,
 		       initrd_size);
-		if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
+		if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
 			printk("initrd extends beyond end of memory "
 			       "(0x%lx > 0x%p)\ndisabling initrd\n",
-			       initrd_end,
-			       phys_to_virt(PFN_PHYS(max_low_pfn)));
+			       PHYSADDR(initrd_end),
+			       PFN_PHYS(max_low_pfn));
 			initrd_start = initrd_end = 0;
-		} 
+		}
 	}
 #endif /* CONFIG_BLK_DEV_INITRD  */
 
@@ -1013,25 +647,6 @@
 	}
 }
 
-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");
-}
-
 static int __init fpu_disable(char *s)
 {
 	mips_cpu.options &= ~MIPS_CPU_FPU;
diff -urN linux-2.4.20-pre6/arch/mips/kernel/signal.c linux-2.4.20-pre7/arch/mips/kernel/signal.c
--- linux-2.4.20-pre6/arch/mips/kernel/signal.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/signal.c	Thu Sep 12 20:01:40 2002
@@ -17,14 +17,14 @@
 #include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
-#include <linux/ptrace.h>
 #include <linux/unistd.h>
 
 #include <asm/asm.h>
 #include <asm/bitops.h>
 #include <asm/cpu.h>
+#include <asm/offset.h>
 #include <asm/pgalloc.h>
-#include <asm/stackframe.h>
+#include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/ucontext.h>
 
@@ -190,7 +190,7 @@
 	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.
@@ -416,15 +416,15 @@
 		goto out;
 
 	/* There exists FP thread state that may be trashed by signal */
-	if (owned_fp) {	
+	if (owned_fp) {
 		/* fp is active.  Save context from FPU */
 		err |= save_fp_context(sc);
 		goto out;
 	}
 
-	/* 
-	 * Someone else has FPU. 
-	 * Copy Thread context into signal context 
+	/*
+	 * Someone else has FPU.
+	 * Copy Thread context into signal context
 	 */
 	err |= save_thread_fp_context(sc);
 
@@ -443,7 +443,7 @@
 	/* 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.
@@ -508,8 +508,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;
 
@@ -583,8 +584,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;
 
@@ -708,7 +710,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:
@@ -732,10 +734,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 -urN linux-2.4.20-pre6/arch/mips/kernel/smp.c linux-2.4.20-pre7/arch/mips/kernel/smp.c
--- linux-2.4.20-pre6/arch/mips/kernel/smp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/smp.c	Thu Sep 12 20:01:40 2002
@@ -8,7 +8,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -17,17 +17,18 @@
  * 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/delay.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/threads.h>
-#include <linux/time.h>
 #include <linux/module.h>
+#include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -36,23 +37,22 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/mmu_context.h>
-#include <asm/delay.h>
 #include <asm/smp.h>
 
-/* Ze Big Kernel Lock! */
+/* The 'big kernel lock' */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
-int smp_threads_ready;
+int smp_threads_ready;	/* Not used */
 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);
 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;
 
 /* These are defined by the board-specific code. */
 
@@ -65,13 +65,13 @@
 
 /*
  * Clear all undefined state in the cpu, set up sp and gp to the passed
- * values, and kick the cpu into smp_bootstrap(); 
+ * values, and kick the cpu into smp_bootstrap();
  */
 void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
 
 /*
  *  After we've done initial boot, this function is called to allow the
- *  board code to clean up state, if needed 
+ *  board code to clean up state, if needed
  */
 void prom_init_secondary(void);
 
@@ -81,6 +81,21 @@
  */
 int prom_setup_smp(void);
 
+void prom_smp_finish(void);
+
+static void smp_tune_scheduling(void)
+{
+}
+
+void __init smp_callin(void)
+{
+#if 0
+	calibrate_delay();
+	smp_store_cpu_info(cpuid);
+#endif
+}
+
+#ifndef CONFIG_SGI_IP27
 /*
  * Hook for doing final board-specific setup after the generic smp setup
  * is done
@@ -96,7 +111,6 @@
 	 * 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();
@@ -106,6 +120,7 @@
 	while (!atomic_read(&smp_commenced));
 	cpu_idle();
 }
+#endif /* CONFIG_SGI_IP27 */
 
 void __init smp_commence(void)
 {
@@ -113,6 +128,11 @@
 	atomic_set(&smp_commenced, 1);
 }
 
+/*
+ * this function sends a 'reschedule' IPI to another CPU.
+ * it goes straight through and wastes no time serializing
+ * anything. Worst case is that we lose a reschedule ...
+ */
 void smp_send_reschedule(int cpu)
 {
 	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
@@ -123,11 +143,17 @@
 struct call_data_struct *call_data;
 
 /*
- * The caller of this wants the passed function to run on every cpu.  If wait
- * is set, wait until all cpus have finished the function before returning.
- * The lock is here to protect the call structure.
+ * 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.
+ *  <retry>     If true, keep retrying until ready.
+ *  <wait>      If true, wait 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.
  */
-int smp_call_function (void (*func) (void *info), void *info, int retry, 
+int smp_call_function (void (*func) (void *info), void *info, int retry,
 								int wait)
 {
 	struct call_data_struct data;
@@ -174,14 +200,14 @@
 
 	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
+	 * 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
+	 * At this point the info structure may be out of scope unless wait==1.
 	 */
 	(*func)(info);
 	if (wait) {
@@ -193,18 +219,23 @@
 
 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();
+	/*
+	 * Remove this CPU:
+	 */
+	clear_bit(smp_processor_id(), &cpu_online_map);
+	/* May need to service _machine_restart IPI */
+	__sti();
+	/* XXXKW wait if available? */
+	for (;;);
 }
 
 void smp_send_stop(void)
 {
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
+	/*
+	 * Fix me: this prevents future IPIs, for example that would
+	 * cause a restart to happen on CPU0.
+	 */
 	smp_num_cpus = 1;
 }
 
@@ -231,11 +262,11 @@
 }
 
 /*
- * The following tlb flush calls are invoked when old translations are 
+ * 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 
+ * 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
diff -urN linux-2.4.20-pre6/arch/mips/kernel/syscall.c linux-2.4.20-pre7/arch/mips/kernel/syscall.c
--- linux-2.4.20-pre6/arch/mips/kernel/syscall.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/syscall.c	Thu Sep 12 20:01:40 2002
@@ -221,7 +221,7 @@
 		return -EFAULT;
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
-  
+
 	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);
diff -urN linux-2.4.20-pre6/arch/mips/kernel/syscalls.h linux-2.4.20-pre7/arch/mips/kernel/syscalls.h
--- linux-2.4.20-pre6/arch/mips/kernel/syscalls.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/syscalls.h	Thu Sep 12 20:01:40 2002
@@ -221,7 +221,7 @@
 SYS(sys_capget, 2)
 SYS(sys_capset, 2)				/* 4205 */
 SYS(sys_sigaltstack, 0)
-SYS(sys_sendfile, 3)
+SYS(sys_sendfile, 4)
 SYS(sys_ni_syscall, 0)
 SYS(sys_ni_syscall, 0)
 SYS(sys_mmap2, 6)				/* 4210 */
@@ -238,18 +238,18 @@
 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_setxattr, 5)
+SYS(sys_lsetxattr, 5)				/* 4225 */
+SYS(sys_fsetxattr, 5)
+SYS(sys_getxattr, 4)
+SYS(sys_lgetxattr, 4)
+SYS(sys_fgetxattr, 4)
+SYS(sys_listxattr, 3)				/* 4230 */
+SYS(sys_llistxattr, 3)
+SYS(sys_flistxattr, 3)
+SYS(sys_removexattr, 2)
+SYS(sys_lremovexattr, 2)
+SYS(sys_fremovexattr, 2)			/* 4235 */
 SYS(sys_tkill, 2)
 SYS(sys_ni_syscall, 0)				/* res. for sendfile64 */
 SYS(sys_ni_syscall, 0)				/* res. for futex */
diff -urN linux-2.4.20-pre6/arch/mips/kernel/sysirix.c linux-2.4.20-pre7/arch/mips/kernel/sysirix.c
--- linux-2.4.20-pre6/arch/mips/kernel/sysirix.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/sysirix.c	Thu Sep 12 20:01:40 2002
@@ -109,7 +109,7 @@
 		if (error)
 			error = (task->run_list.next != NULL);
 		read_unlock(&tasklist_lock);
-		/* Can _your_ OS find this out that fast? */ 
+		/* Can _your_ OS find this out that fast? */
 		break;
 	}
 
@@ -332,7 +332,7 @@
 		       current->comm, current->pid, name, value, retval);
 /*		if (retval == PROM_ENOENT)
 		  	retval = -ENOENT; */
-		break;				   
+		break;
 	}
 #endif
 
@@ -505,7 +505,7 @@
 		}
 		break;
 	}
-	
+
 	default:
 		printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
 		retval = -EINVAL;
@@ -1071,7 +1071,7 @@
 		if (flags & IRIX_MAP_AUTOGROW) {
 			unsigned long old_pos;
 			long max_size = offset + len;
-			
+
 			if (max_size > file->f_dentry->d_inode->i_size) {
 				old_pos = sys_lseek (fd, max_size - 1, 0);
 				sys_write (fd, "", 1);
diff -urN linux-2.4.20-pre6/arch/mips/kernel/sysmips.c linux-2.4.20-pre7/arch/mips/kernel/sysmips.c
--- linux-2.4.20-pre6/arch/mips/kernel/sysmips.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/sysmips.c	Thu Sep 12 20:01:40 2002
@@ -61,13 +61,13 @@
 		name = (char *) arg1;
 
 		len = strncpy_from_user(nodename, name, sizeof(nodename));
-		if (len < 0) 
+		if (len < 0)
 			return -EFAULT;
 
 		down_write(&uts_sem);
 		strncpy(system_utsname.nodename, name, len);
+		system_utsname.nodename[len] = '\0';
 		up_write(&uts_sem);
-		system_utsname.nodename[len] = '\0'; 
 		return 0;
 	}
 
diff -urN linux-2.4.20-pre6/arch/mips/kernel/time.c linux-2.4.20-pre7/arch/mips/kernel/time.c
--- linux-2.4.20-pre6/arch/mips/kernel/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/time.c	Thu Sep 12 20:01:40 2002
@@ -2,8 +2,8 @@
  * 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. 
+ * 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
@@ -289,9 +289,9 @@
 
 /*
  * local_timer_interrupt() does profiling and process accounting
- * on a per-CPU basis.  
+ * on a per-CPU basis.
  *
- * In UP mode, it is invoked from the (global) timer_interrupt.  
+ * 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
@@ -368,7 +368,7 @@
 		if (rtc_set_time(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
-			last_rtc_update = xtime.tv_sec - 600; 
+			last_rtc_update = xtime.tv_sec - 600;
 			/* do it again in 60 s */
 		}
 	}
@@ -384,9 +384,9 @@
 	}
 
 #if !defined(CONFIG_SMP)
-	/* 
+	/*
 	 * In UP mode, we call local_timer_interrupt() to do profiling
-	 * and process accouting.  
+	 * and process accouting.
 	 *
 	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
 	 * low-level local timer interrupt handler.
@@ -396,7 +396,7 @@
 #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.
@@ -418,7 +418,7 @@
 
 	/* we keep interrupt disabled all the time */
 	timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -434,7 +434,7 @@
 
 	/* we keep interrupt disabled all the time */
 	local_timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -444,19 +444,19 @@
 /*
  * time_init() - it does the following things.
  *
- * 1) board_time_init() - 
- * 	a) (optional) set up RTC routines, 
+ * 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() - 
+ * 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;
@@ -497,10 +497,12 @@
 		/* 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) {
+		u32 count;
+
 		cycles_per_jiffy = mips_counter_frequency / HZ;
 
 		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */
@@ -508,16 +510,24 @@
 		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
 		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
 		sll32_usecs_per_cycle *= 10;
+
+		/*
+		 * For those using cpu counter as timer,  this sets up the
+		 * first interrupt
+		 */
+		count = read_32bit_cp0_register(CP0_COUNT);
+		write_32bit_cp0_register (CP0_COMPARE,
+					  count + cycles_per_jiffy);
 	}
 
-	/* 
+	/*
 	 * Call board specific timer interrupt setup.
 	 *
-	 * this pointer must be setup in machine setup routine. 
+	 * 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 
+	 * 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.
 	 */
diff -urN linux-2.4.20-pre6/arch/mips/kernel/traps.c linux-2.4.20-pre7/arch/mips/kernel/traps.c
--- linux-2.4.20-pre6/arch/mips/kernel/traps.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/traps.c	Thu Sep 12 20:01:40 2002
@@ -32,6 +32,7 @@
 #include <asm/io.h>
 #include <asm/siginfo.h>
 #include <asm/watch.h>
+#include <asm/types.h>
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/uaccess.h>
@@ -64,7 +65,8 @@
 extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
-extern int fpu_emulator_cop1Handler(struct pt_regs *);
+extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx);
 
 char watch_available = 0;
 
@@ -180,61 +182,95 @@
 }
 
 /*
+ * If the address is either in the .text section of the
+ * kernel, or in the vmalloc'ed module regions, it *may*
+ * be the address of a calling routine
+ */
+
+#ifdef CONFIG_MODULES
+
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+	int retval = 0;
+	struct module *mod;
+
+	if (addr >= (long) &_stext && addr <= (long) &_etext)
+		return 1;
+
+	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;
+		}
+	}
+
+	return retval;
+}
+
+#else
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+
+	return (addr >= (long) &_stext && addr <= (long) &_etext);
+}
+
+#endif
+
+/*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
  */
-void show_stack(unsigned int *sp)
+void show_stack(long *sp)
 {
 	int i;
-	unsigned int *stack;
+	long stackdata;
 
-	stack = sp ? sp : (unsigned int *)&sp;
-	i = 0;
+	sp = sp ? sp : (long *)&sp;
 
-	printk("Stack:");
-	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
-		unsigned long stackdata;
-
-		if (__get_user(stackdata, stack++)) {
-			printk(" (Bad stack address)");
+	printk("Stack:   ");
+	i = 1;
+	while ((long) sp & (PAGE_SIZE - 1)) {
+		if (i && ((i % 8) == 0))
+			printk("\n");
+		if (i > 40) {
+			printk(" ...");
 			break;
 		}
 
-		printk(" %08lx", stackdata);
-
-		if (++i > 40) {
-			printk(" ...");
+		if (__get_user(stackdata, sp++)) {
+			printk(" (Bad stack address)");
 			break;
 		}
 
-		if (i % 8 == 0)
-			printk("\n      ");
+		printk(" %08lx", stackdata);
+		i++;
 	}
+	printk("\n");
 }
 
-void show_trace(unsigned int *sp)
+void show_trace(long *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;
+	long addr;
 
-	stack = sp ? sp : (unsigned int *) &sp;
-	i = 0;
+	sp = sp ? sp : (long *) &sp;
 
-	kernel_start = (unsigned long) &_stext;
-	kernel_end = (unsigned long) &_etext;
-	module_start = VMALLOC_START;
-	module_end = module_start + MODULE_RANGE;
+	printk("Call Trace:  ");
+	i = 1;
+	while ((long) sp & (PAGE_SIZE - 1)) {
 
-	printk("\nCall Trace:");
-
-	while ((unsigned long) stack & (PAGE_SIZE -1)) {
-		unsigned long addr;
-
-		if (__get_user(addr, stack++)) {
+		if (__get_user(addr, sp++)) {
+			if (i && ((i % 6) == 0))
+				printk("\n");
 			printk(" (Bad stack address)\n");
 			break;
 		}
@@ -248,27 +284,24 @@
 		 * out the call path that was taken.
 		 */
 
-		if ((addr >= kernel_start && addr < kernel_end) ||
-		    (addr >= module_start && addr < module_end)) { 
-
-			printk(" [<%08lx>]", addr);
-			if (column++ == 5) {
+		if (kernel_text_address(addr)) {
+			if (i && ((i % 6) == 0))
 				printk("\n");
-				column = 0;
-			}
-			if (++i > 40) {
+			if (i > 40) {
 				printk(" ...");
 				break;
 			}
+
+			printk(" [<%08lx>]", addr);
+			i++;
 		}
 	}
-	if (column != 0)
-		printk("\n");
+	printk("\n");
 }
 
 void show_trace_task(struct task_struct *tsk)
 {
-	show_trace((unsigned int *)tsk->thread.reg29);
+	show_trace((long *)tsk->thread.reg29);
 }
 
 void show_code(unsigned int *pc)
@@ -320,33 +353,33 @@
 	show_regs(regs);
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, (unsigned long) current);
-	show_stack((unsigned int *) regs->regs[29]);
-	show_trace((unsigned int *) regs->regs[29]);
+	show_stack((long *) regs->regs[29]);
+	show_trace((long *) 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)
+void __die(const char * str, struct pt_regs * regs, const char * file,
+	   const char * func, unsigned long line)
 {
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	printk("%s", str);
-	if (where)
-		printk(" in %s, line %ld", where, line);
+	if (file && func)
+		printk(" in %s:%s, line %ld", file, func, line);
 	printk(":\n");
 	show_registers(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
 
-void __die_if_kernel(const char * str, struct pt_regs * regs, const char *where,
-	unsigned long line)
+void __die_if_kernel(const char * str, struct pt_regs * regs,
+		     const char * file, const char * func, unsigned long line)
 {
 	if (!user_mode(regs))
-		__die(str, regs, where, line);
+		__die(str, regs, file, func, line);
 }
 
 extern const struct exception_table_entry __start___dbe_table[];
@@ -461,10 +494,16 @@
 
 asmlinkage void do_ov(struct pt_regs *regs)
 {
+	siginfo_t info;
+
 	if (compute_return_epc(regs))
 		return;
 
-	force_sig(SIGFPE, current);
+	info.si_code = FPE_INTOVF;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->cp0_epc;
+	force_sig_info(SIGFPE, &info, current);
 }
 
 /*
@@ -473,27 +512,26 @@
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
 	if (fcr31 & FPU_CSR_UNI_X) {
-		extern void save_fp(struct task_struct *);
-		extern void restore_fp(struct task_struct *);
 		int sig;
+
 		/*
-	 	 * Unimplemented operation exception.  If we've got the
-	 	 * full software emulator on-board, let's use it...
+	 	 * 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.
+		 * 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);
+		sig = fpu_emulator_cop1Handler (0, regs,
+			&current->thread.fpu.soft);
 
-		/* 
-		 * We can't allow the emulated instruction to leave any of 
+		/*
+		 * 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;
@@ -504,8 +542,8 @@
 		/* If something went wrong, signal */
 		if (sig)
 		{
-			/* 
-			 * Return EPC is not calculated in the FPU emulator, 
+			/*
+			 * Return EPC is not calculated in the FPU emulator,
 			 * if a signal is being send. So we calculate it here.
 			 */
 			compute_return_epc(regs);
@@ -522,9 +560,9 @@
 
 static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
 {
-	unsigned int *epc;
+	unsigned long *epc;
 
-	epc = (unsigned int *) regs->cp0_epc +
+	epc = (unsigned long *) regs->cp0_epc +
 	      ((regs->cp0_cause & CAUSEF_BD) != 0);
 	if (!get_user(*opcode, epc))
 		return 0;
@@ -535,14 +573,11 @@
 
 asmlinkage void do_bp(struct pt_regs *regs)
 {
-	siginfo_t info;
 	unsigned int opcode, bcode;
-	unsigned int *epc;
+	siginfo_t info;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
@@ -572,35 +607,30 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
 asmlinkage void do_tr(struct pt_regs *regs)
 {
 	siginfo_t info;
-	unsigned int opcode, bcode;
-	unsigned *epc;
+	unsigned int opcode, tcode = 0;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
-	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+	/* Immediate versions don't provide a code.  */
+	if (!(opcode & OPCODE))
+		tcode = ((opcode >> 6) & ((1 << 20) - 1));
 
 	/*
-	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
-	 * insns, even for break codes that indicate arithmetic failures.
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
+	 * insns, even for trap codes that indicate arithmetic failures.
 	 * Weird ...)
 	 * But should we continue the brokenness???  --macro
 	 */
-	switch (bcode) {
+	switch (tcode) {
 	case 6:
 	case 7:
-		if (bcode == 7)
+		if (tcode == 7)
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -612,10 +642,6 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
 /*
@@ -627,8 +653,7 @@
  */
 asmlinkage void do_ri(struct pt_regs *regs)
 {
-	if (!user_mode(regs))
-		BUG();
+	die_if_kernel("Reserved instruction in kernel code", regs);
 
 #ifndef CONFIG_CPU_HAS_LLSC
 
@@ -660,9 +685,6 @@
 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;
 
@@ -696,12 +718,11 @@
 			current->used_math = 1;
 		}
 	}
-	sig = fpu_emulator_cop1Handler(regs);
+	sig = fpu_emulator_cop1Handler(0, regs, &current->thread.fpu.soft);
 	last_task_used_math = current;
-	if (sig)
-	{
-		/* 
-		 * Return EPC is not calculated in the FPU emulator, if 
+	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);
@@ -738,8 +759,14 @@
 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.");
+	dump_tlb_all();
+	/*
+	 * Some chips may have other causes of machine check (e.g. SB1
+	 * graduation timer)
+	 */
+	panic("Caught Machine Check exception - %scaused by multiple "
+	      "matching entries in the TLB.",
+	      (regs->cp0_status & ST0_TS) ? "" : "not ");
 }
 
 asmlinkage void do_reserved(struct pt_regs *regs)
@@ -774,7 +801,7 @@
 		       "MIPS 5KC CPUs.\n");
 		write_32bit_cp0_register(CP0_ECC,
 		                         read_32bit_cp0_register(CP0_ECC)
-		                         | 0x80000000); 
+		                         | 0x80000000);
 		break;
 	default:
 		break;
@@ -827,9 +854,9 @@
         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); 
+        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
@@ -869,10 +896,10 @@
  */
 void *set_except_vector(int n, void *addr)
 {
-	unsigned handler = (unsigned long) addr;
-	unsigned old_handler = exception_handlers[n];
-	exception_handlers[n] = handler;
+	unsigned long handler = (unsigned long) addr;
+	unsigned long old_handler = exception_handlers[n];
 
+	exception_handlers[n] = handler;
 	if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
 		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
 		                                 (0x03ffffff & (handler >> 2));
@@ -928,8 +955,8 @@
 	for (i = 0; i <= 31; i++)
 		set_except_vector(i, handle_reserved);
 
-	/* 
-	 * Copy the EJTAG debug exception vector handler code to it's final 
+	/*
+	 * Copy the EJTAG debug exception vector handler code to it's final
 	 * destination.
 	 */
 	if (mips_cpu.options & MIPS_CPU_EJTAG)
diff -urN linux-2.4.20-pre6/arch/mips/kernel/unaligned.c linux-2.4.20-pre7/arch/mips/kernel/unaligned.c
--- linux-2.4.20-pre6/arch/mips/kernel/unaligned.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/kernel/unaligned.c	Thu Sep 12 20:01:40 2002
@@ -41,7 +41,7 @@
  *
  * #include <stdio.h>
  * #include <asm/sysmips.h>
- * 
+ *
  * struct foo {
  *         unsigned char bar[8];
  * };
@@ -368,7 +368,7 @@
 	unsigned long pc;
 	extern int do_dsemulret(struct pt_regs *);
 
-	/* 
+	/*
 	 * Address errors may be deliberately induced
 	 * by the FPU emulator to take retake control
 	 * of the CPU after executing the instruction
diff -urN linux-2.4.20-pre6/arch/mips/lib/Makefile linux-2.4.20-pre7/arch/mips/lib/Makefile
--- linux-2.4.20-pre6/arch/mips/lib/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/Makefile	Thu Sep 12 20:01:40 2002
@@ -12,9 +12,9 @@
 				   strnlen_user.o
 
 ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y)
-  obj-y	+= r3k_dump_tlb.o 
+  obj-y	+= r3k_dump_tlb.o
 else
-  obj-y	+= dump_tlb.o 
+  obj-y	+= dump_tlb.o
 endif
 
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy-no.o floppy-std.o
diff -urN linux-2.4.20-pre6/arch/mips/lib/csum_partial_copy.c linux-2.4.20-pre7/arch/mips/lib/csum_partial_copy.c
--- linux-2.4.20-pre6/arch/mips/lib/csum_partial_copy.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/csum_partial_copy.c	Thu Sep 12 20:01:40 2002
@@ -23,7 +23,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy(const char *src, char *dst, 
+unsigned int csum_partial_copy(const char *src, char *dst,
                                int len, unsigned int sum)
 {
 	/*
@@ -51,6 +51,6 @@
 		memset(dst + len - missing, 0, missing);
 		*err_ptr = -EFAULT;
 	}
-		
+
 	return csum_partial(dst, len, sum);
 }
diff -urN linux-2.4.20-pre6/arch/mips/lib/floppy-std.c linux-2.4.20-pre7/arch/mips/lib/floppy-std.c
--- linux-2.4.20-pre6/arch/mips/lib/floppy-std.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/floppy-std.c	Thu Sep 12 20:01:40 2002
@@ -111,8 +111,8 @@
 }
 
 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 -urN linux-2.4.20-pre6/arch/mips/lib/ide-no.c linux-2.4.20-pre7/arch/mips/lib/ide-no.c
--- linux-2.4.20-pre6/arch/mips/lib/ide-no.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/ide-no.c	Thu Sep 12 20:01:40 2002
@@ -35,7 +35,7 @@
                               void *dev_id)
 {
 	panic("no_no_ide_request_irq called - shouldn't happen");
-}			
+}
 
 static void no_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -urN linux-2.4.20-pre6/arch/mips/lib/ide-std.c linux-2.4.20-pre7/arch/mips/lib/ide-std.c
--- linux-2.4.20-pre6/arch/mips/lib/ide-std.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips/lib/ide-std.c	Thu Sep 12 20:01:40 2002
@@ -68,7 +68,7 @@
                                 void *dev_id)
 {
 	return request_irq(irq, handler, flags, device, dev_id);
-}			
+}
 
 static void std_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -urN linux-2.4.20-pre6/arch/mips/lib/memcpy.S linux-2.4.20-pre7/arch/mips/lib/memcpy.S
--- linux-2.4.20-pre6/arch/mips/lib/memcpy.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/memcpy.S	Thu Sep 12 20:01:40 2002
@@ -249,7 +249,7 @@
 EXC(	LOAD	 t0, 0(src),		l_exc)
 	ADD	src, src, NBYTES
 	SUB	len, len, NBYTES
-EXC(	STORE	t0, 0(dst),		s_exc)
+EXC(	STORE	t0, 0(dst),		s_exc_p1u)
 	bne	rem, len, 1b
 	 ADD	dst, dst, NBYTES
 
diff -urN linux-2.4.20-pre6/arch/mips/lib/memset.S linux-2.4.20-pre7/arch/mips/lib/memset.S
--- linux-2.4.20-pre6/arch/mips/lib/memset.S	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips/lib/memset.S	Thu Sep 12 20:01:40 2002
@@ -54,7 +54,6 @@
 1:
 
 EXPORT(__bzero)
-	.type   __bzero, @function
 	sltiu	t0, a2, 4			/* very small region? */
 	bnez	t0, small_memset
 	 andi	t0, a0, 3			/* aligned? */
@@ -84,13 +83,17 @@
 	.set	noreorder
 
 memset_partial:
-	la	t1, 2f				/* where to start */
+	PTR_LA	t1, 2f				/* where to start */
 	subu	t1, t0
 	jr	t1
 	 addu	a0, t0				/* dest ptr */
 
+	.set	push
+	.set	noreorder
+	.set	nomacro
 	F_FILL64(a0, -64, a1, partial_fixup)	/* ... but first do wrds ... */
-2:	andi	a2, 3				/* 0 <= n <= 3 to go */
+2:	.set	pop
+	andi	a2, 3				/* 0 <= n <= 3 to go */
 
 	beqz	a2, 1f
 	 addu	a0, a2				/* What's left */
diff -urN linux-2.4.20-pre6/arch/mips/lib/strlen_user.S linux-2.4.20-pre7/arch/mips/lib/strlen_user.S
--- linux-2.4.20-pre6/arch/mips/lib/strlen_user.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/strlen_user.S	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 	and	v0, a0
 	bltz	v0, fault
 
-EXPORT(__strlen_user_nocheck_asm)
+FEXPORT(__strlen_user_nocheck_asm)
 	move	v0, a0
 1:	EX(lb, t0, (v0), fault)
 	addiu	v0, 1
@@ -36,9 +36,5 @@
 	jr	ra
 	END(__strlen_user_asm)
 
-	.section __ex_table,"a"
-	PTR	1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -urN linux-2.4.20-pre6/arch/mips/lib/strnlen_user.S linux-2.4.20-pre7/arch/mips/lib/strnlen_user.S
--- linux-2.4.20-pre6/arch/mips/lib/strnlen_user.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/lib/strnlen_user.S	Thu Sep 12 20:01:40 2002
@@ -31,7 +31,7 @@
 	and	v0, a0
 	bltz	v0, fault
 
-EXPORT(__strnlen_user_nocheck_asm)
+FEXPORT(__strnlen_user_nocheck_asm)
 	.type	__strnlen_user_nocheck_asm,@function
 	move	v0, a0
 	addu	a1, a0			# stop pointer
@@ -45,9 +45,5 @@
 	jr	ra
 	END(__strnlen_user_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -urN linux-2.4.20-pre6/arch/mips/lib/tinycon.c linux-2.4.20-pre7/arch/mips/lib/tinycon.c
--- linux-2.4.20-pre6/arch/mips/lib/tinycon.c	Thu Jun 26 12:33:37 1997
+++ linux-2.4.20-pre7/arch/mips/lib/tinycon.c	Thu Sep 12 20:01:40 2002
@@ -38,7 +38,7 @@
   cursor_y = 0;
 
   vram_addr = (unsigned short *)0xb00b8000;
-  
+
   console_needs_init = 0;
 }
 
@@ -87,7 +87,7 @@
     *(caddr++) = *(caddr + size_x);
 
   /* blank last line */
-  
+
   caddr = vram_addr + (size_x * (size_y-1));
   for(i=0; i<size_x; i++)
     *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' ';
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/Makefile linux-2.4.20-pre7/arch/mips/math-emu/Makefile
--- linux-2.4.20-pre6/arch/mips/math-emu/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/Makefile	Thu Sep 12 20:01:40 2002
@@ -16,6 +16,6 @@
 	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
 	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
 	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
-	   dp_sqrt.o sp_sqrt.o kernel_linkage.o
+	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/cp1emu.c linux-2.4.20-pre7/arch/mips/math-emu/cp1emu.c
--- linux-2.4.20-pre6/arch/mips/math-emu/cp1emu.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/cp1emu.c	Thu Sep 12 20:01:40 2002
@@ -1,6 +1,6 @@
 /*
  * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
- * 
+ *
  * MIPS floating point support
  * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
  * http://www.algor.co.uk
@@ -23,38 +23,30 @@
  *
  * A complete emulator for MIPS coprocessor 1 instructions.  This is
  * required for #float(switch) or #float(trap), where it catches all
- * COP1 instructions via the "CoProcessor Unusable" exception.  
+ * COP1 instructions via the "CoProcessor Unusable" exception.
  *
  * More surprisingly it is also required for #float(ieee), to help out
  * the hardware fpu at the boundaries of the IEEE-754 representation
  * (denormalised values, infinities, underflow, etc).  It is made
  * quite nasty because emulation of some non-COP1 instructions is
  * required, e.g. in branch delay slots.
- * 
- * Note if you know that you won't have an fpu, then you'll get much 
+ *
+ * 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>
-#include <linux/smp_lock.h>
-
-#include <asm/asm.h>
-#include <asm/branch.h>
+#include <asm/inst.h>
 #include <asm/bootinfo.h>
-#include <asm/byteorder.h>
 #include <asm/cpu.h>
-#include <asm/inst.h>
-#include <asm/uaccess.h>
 #include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
 #include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
 #include <asm/fpu_emulator.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
 
 #include "ieee754.h"
+#include "dsemul.h"
 
 /* Strap kernel emulator for full MIPS IV emulation */
 
@@ -63,20 +55,14 @@
 #endif
 #define __mips 4
 
-typedef void *vaddr_t;
-
-/* Function which emulates the instruction in a branch delay slot. */
-
-static int mips_dsemul(struct pt_regs *, mips_instruction, unsigned long);
-
 /* Function which emulates a floating point instruction. */
 
 static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *,
-	 mips_instruction);
+	mips_instruction);
 
 #if __mips >= 4 && __mips != 32
 static int fpux_emu(struct pt_regs *,
-		    struct mips_fpu_soft_struct *, mips_instruction);
+	struct mips_fpu_soft_struct *, mips_instruction);
 #endif
 
 /* Further private data for which no space exists in mips_fpu_soft_struct */
@@ -108,8 +94,7 @@
 #endif
 
 
-
-/* 
+/*
  * Redundant with logic already in kernel/branch.c,
  * embedded in compute_return_epc.  At some point,
  * a single subroutine should be used across both
@@ -165,46 +150,70 @@
 	return 0;
 }
 
-#define REG_TO_VA (vaddr_t)
-#define VA_TO_REG (unsigned long)
-
 /*
  * 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
  * FPRs are desired, there needs to be a flip-flop that can be written
- * to one at that bit position.  In any case, normal MIPS ABI uses
+ * to one at that bit position.  In any case, O32 MIPS ABI uses
  * only the even FPRs (Status.FR = 0).
  */
 
 #define CP0_STATUS_FR_SUPPORT
 
+#ifdef CP0_STATUS_FR_SUPPORT
+#define FR_BIT ST0_FR
+#else
+#define FR_BIT 0
+#endif
+
+#define SIFROMREG(si,x)	((si) = \
+			(xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+			(int)ctx->regs[x] : \
+			(int)(ctx->regs[x & ~1] >> 32 ))
+#define SITOREG(si,x)	(ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \
+			(xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+			ctx->regs[x & ~1] >> 32 << 32 | (u32)(si) : \
+			ctx->regs[x & ~1] << 32 >> 32 | (u64)(si) << 32)
+
+#define DIFROMREG(di,x)	((di) = \
+			ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)])
+#define DITOREG(di,x)	(ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
+			= (di))
+#define DIFROMREG(di,x)	((di) = \
+			ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)])
+#define DITOREG(di,x)	(ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
+			= (di))
+
+#define SPFROMREG(sp,x)	SIFROMREG((sp).bits,x)
+#define SPTOREG(sp,x)	SITOREG((sp).bits,x)
+#define DPFROMREG(dp,x)	DIFROMREG((dp).bits,x)
+#define DPTOREG(dp,x)	DITOREG((dp).bits,x)
+
 /*
  * Emulate the single floating point instruction pointed at by EPC.
  * Two instructions if the instruction is in a branch delay slot.
  */
 
-static int cop1Emulate(struct pt_regs *regs, struct mips_fpu_soft_struct *ctx)
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
 {
-	vaddr_t emulpc, contpc;
 	mips_instruction ir;
+	vaddr_t emulpc, contpc;
 	unsigned int cond;
-	int err = 0;
 
-	err = get_user(ir, (mips_instruction *) regs->cp0_epc);
-	if (err) {
+	if (get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) {
 		fpuemuprivate.stats.errors++;
 		return SIGBUS;
 	}
 
 	/* XXX NEC Vr54xx bug workaround */
-	if ((regs->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
-		regs->cp0_cause &= ~CAUSEF_BD;
+	if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
+		xcp->cp0_cause &= ~CAUSEF_BD;
 
-	if (regs->cp0_cause & CAUSEF_BD) {
+	if (xcp->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
-		 * BEFORE we do the cop1 instruction. 
+		 * BEFORE we do the cop1 instruction.
 		 *
 		 * This branch could be a COP1 branch, but in that case we
 		 * would have had a trap for that instruction, and would not
@@ -213,368 +222,206 @@
 		 * Linux MIPS branch emulator operates on context, updating the
 		 * cp0_epc.
 		 */
-		emulpc = REG_TO_VA(regs->cp0_epc + 4);	/* Snapshot emulation target */
+		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
 
-		if (__compute_return_epc(regs)) {
+		if (__compute_return_epc(xcp)) {
 #ifdef CP1DBG
 			printk("failed to emulate branch at %p\n",
-				    REG_TO_VA(regs->cp0_epc));
+				REG_TO_VA(xcp->cp0_epc));
 #endif
 			return SIGILL;
 		}
-		err = get_user(ir, (mips_instruction *) emulpc);
-		if (err) {
+		if (get_user(ir, (mips_instruction *) emulpc)) {
 			fpuemuprivate.stats.errors++;
 			return SIGBUS;
 		}
 		/* __computer_return_epc() will have updated cp0_epc */
-		contpc = REG_TO_VA regs->cp0_epc;
+		contpc = REG_TO_VA xcp->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 regs->cp0_epc;
-		contpc = REG_TO_VA regs->cp0_epc + 4;
+		xcp->cp0_epc = VA_TO_REG emulpc - 4;
+	}
+	else {
+		emulpc = REG_TO_VA xcp->cp0_epc;
+		contpc = REG_TO_VA(xcp->cp0_epc + 4);
 	}
 
-emul:
+      emul:
 	fpuemuprivate.stats.emulated++;
 	switch (MIPSInst_OPCODE(ir)) {
-#ifdef CP0_STATUS_FR_SUPPORT
-		/* R4000+ 64-bit fpu registers */
 #ifndef SINGLE_ONLY_FPU
-	case ldc1_op:
-		{
-			u64 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-
-			if (!(regs->cp0_status & ST0_FR))
-				ft &= ~1;
-			err = get_user(ctx->regs[ft], va);
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
+	case ldc1_op:{
+		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u64 val;
+
+		fpuemuprivate.stats.loads++;
+		if (get_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
+		DITOREG(val, MIPSInst_RT(ir));
 		break;
+	}
 
-	case sdc1_op:
-		{
-			fpureg_t *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			               MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-
-			if (!(regs->cp0_status & ST0_FR))
-				ft &= ~1;
-			fpuemuprivate.stats.stores++;
-			if (put_user(ctx->regs[ft], va)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
+	case sdc1_op:{
+		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u64 val;
+
+		fpuemuprivate.stats.stores++;
+		DIFROMREG(val, MIPSInst_RT(ir));
+		if (put_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
 		break;
+	}
 #endif
 
-	case lwc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			               MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-			u32 val;
+	case lwc1_op:{
+		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u32 val;
 
-			fpuemuprivate.stats.loads++;
-			err = get_user(val, va);
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-			if (regs->cp0_status & ST0_FR) {
-				/* load whole register */
-				ctx->regs[ft] = (s64) val;
-			} else if (ft & 1) {
-				/* load to m.s. 32 bits */
-#ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				ctx->regs[(ft & ~1)] &= 0xffffffff;
-				ctx->regs[(ft & ~1)] |= (fpureg_t) val << 32;
-#endif
-			} else {
-				/* load to l.s. 32 bits */
-				ctx->regs[ft] &= ~0xffffffffLL;
-				ctx->regs[ft] |= val;
-			}
+		fpuemuprivate.stats.loads++;
+		if (get_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
-		break;
-
-	case swc1_op:
-		{
-			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 (regs->cp0_status & ST0_FR) {
-				/* store whole register */
-				val = ctx->regs[ft];
-			} else if (ft & 1) {
 #ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				/* store from m.s. 32 bits */
-				val = ctx->regs[(ft & ~1)] >> 32;
-#endif
-			} else {
-				/* store from l.s. 32 bits */
-				val = ctx->regs[ft];
-			}
-			if (put_user(val, va)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-#else				/* old 32-bit fpu registers */
-	case lwc1_op:
-		{
-			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++;
-				return SIGBUS;
-			}
-		}
-		break;
-
-	case swc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			fpuemuprivate.stats.stores++;
-			if (put_user(ctx->regs[MIPSInst_RT(ir)], va)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
+		if (MIPSInst_RT(ir) & 1) {
+			/* illegal register in single-float mode */
+			return SIGILL;
 		}
-		break;
-	case ldc1_op:
-		{
-			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__)
-			err = get_user(ctx->regs[rt + 1], va + 0);
-			err |= get_user(ctx->regs[rt + 0], va + 1);
-#else
-			err = get_user(ctx->regs[rt + 0], va + 0);
-			err |= get_user(ctx->regs[rt + 1], va + 1);
 #endif
-			if (err)
-				return SIGBUS;
-		}
+		SITOREG(val, MIPSInst_RT(ir));
 		break;
+	}
 
-	case sdc1_op:
-		{
-			u32 *va = REG_TO_VA(regs->regs[MIPSInst_RS(ir)]) +
-			          MIPSInst_SIMM(ir);
-			unsigned int rt = MIPSInst_RT(ir) & ~1;
+	case swc1_op:{
+		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
+			MIPSInst_SIMM(ir));
+		u32 val;
 
-			fpuemuprivate.stats.stores++;
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-			if (put_user(ctx->regs[rt + 1], va + 0)
-			    || put_user(ctx->regs[rt + 0], va + 1))
-				return SIGBUS;
-#else
-			if (put_user(ctx->regs[rt + 0], va + 0)
-			    || put_user(ctx->regs[rt + 1], va + 1))
-				return SIGBUS;
+		fpuemuprivate.stats.stores++;
+#ifdef SINGLE_ONLY_FPU
+		if (MIPSInst_RT(ir) & 1) {
+			/* illegal register in single-float mode */
+			return SIGILL;
+		}
 #endif
+		SIFROMREG(val, MIPSInst_RT(ir));
+		if (put_user(val, va)) {
+			fpuemuprivate.stats.errors++;
+			return SIGBUS;
 		}
 		break;
-#endif
+	}
 
 	case cop1_op:
 		switch (MIPSInst_RS(ir)) {
 
-#ifdef CP0_STATUS_FR_SUPPORT
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
 		case dmfc_op:
 			/* copregister fs -> gpr[rt] */
 			if (MIPSInst_RT(ir) != 0) {
-				int fs = MIPSInst_RD(ir);
-				if (!(regs->cp0_status & ST0_FR))
-					fs &= ~1;
-				regs->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
+				DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+					MIPSInst_RD(ir));
 			}
 			break;
 
-		case dmtc_op: {
+		case dmtc_op:
 			/* copregister fs <- rt */
-				fpureg_t value;
-				int fs = MIPSInst_RD(ir);
-				if (!(regs->cp0_status & ST0_FR))
-					fs &= ~1;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : regs->regs[MIPSInst_RT(ir)];
-				ctx->regs[fs] = value;
+			DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
 			break;
-		}
 #endif
 
 		case mfc_op:
 			/* copregister rd -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				/* default value from l.s. 32 bits */
-				int value = ctx->regs[MIPSInst_RD(ir)];
-				if (MIPSInst_RD(ir) & 1) {
 #ifdef SINGLE_ONLY_FPU
-					/* illegal register in single-float mode */
-					return SIGILL;
-#else
-					if (!(regs->cp0_status & ST0_FR)) {
-						/* move from m.s. 32 bits */
-						value =
-						    ctx->
-						    regs[MIPSInst_RD(ir) &
-							 ~1] >> 32;
-					}
-#endif
-				}
-				regs->regs[MIPSInst_RT(ir)] = value;
+			if (MIPSInst_RD(ir) & 1) {
+				/* illegal register in single-float mode */
+				return SIGILL;
 			}
-			break;
-
-		case mtc_op:
-			/* copregister rd <- rt */
-			{
-				fpureg_t value;
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value =
-					    (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 (!(regs->cp0_status & ST0_FR)) {
-						/* move to m.s. 32 bits */
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] |=
-						    value << 32;
-						break;
-					}
 #endif
-				}
-				/* move to l.s. 32 bits */
-				ctx->regs[MIPSInst_RD(ir)] &=
-				    ~0xffffffffLL;
-				ctx->regs[MIPSInst_RD(ir)] |= value;
-			}
-			break;
-#else
-
-		case mfc_op:
-			/* copregister rd -> gpr[rt] */
 			if (MIPSInst_RT(ir) != 0) {
-				unsigned value =
-				    ctx->regs[MIPSInst_RD(ir)];
-				regs->regs[MIPSInst_RT(ir)] = value;
+				SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+					MIPSInst_RD(ir));
 			}
 			break;
 
 		case mtc_op:
 			/* copregister rd <- rt */
-			{
-				unsigned value;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : regs->regs[MIPSInst_RT(ir)];
-				ctx->regs[MIPSInst_RD(ir)] = value;
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_RD(ir) & 1) {
+				/* illegal register in single-float mode */
+				return SIGILL;
 			}
-			break;
 #endif
+			SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+			break;
 
-		case cfc_op:
+		case cfc_op:{
 			/* cop control register rd -> gpr[rt] */
-			{
-				unsigned value;
+			u32 value;
 
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
-					value = ctx->sr;
+			if (ir == CP1UNDEF) {
+				return do_dsemulret(xcp);
+			}
+			if (MIPSInst_RD(ir) == FPCREG_CSR) {
+				value = ctx->sr;
 #ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]<-csr=%08x\n",
-					     REG_TO_VA(regs->cp0_epc),
-					     MIPSInst_RT(ir), value);
+				printk("%p gpr[%d]<-csr=%08x\n",
+					REG_TO_VA(xcp->cp0_epc),
+					MIPSInst_RT(ir), value);
 #endif
-				} else if (MIPSInst_RD(ir) == FPCREG_RID)
-					value = 0;
-				else
-					value = 0;
-				if (MIPSInst_RT(ir))
-					regs->regs[MIPSInst_RT(ir)] = value;
 			}
+			else if (MIPSInst_RD(ir) == FPCREG_RID)
+				value = 0;
+			else
+				value = 0;
+			if (MIPSInst_RT(ir))
+				xcp->regs[MIPSInst_RT(ir)] = value;
 			break;
+		}
 
-		case ctc_op:
+		case ctc_op:{
 			/* copregister rd <- rt */
-			{
-				unsigned value;
-
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value = regs->regs[MIPSInst_RT(ir)];
+			u32 value;
 
-				/* we only have one writable control reg
-				 */
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
+			if (MIPSInst_RT(ir) == 0)
+				value = 0;
+			else
+				value = xcp->regs[MIPSInst_RT(ir)];
+
+			/* we only have one writable control reg
+			 */
+			if (MIPSInst_RD(ir) == FPCREG_CSR) {
 #ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]->csr=%08x\n",
-					     REG_TO_VA(regs->cp0_epc),
-					     MIPSInst_RT(ir), value);
-#endif
-					ctx->sr = value;
-					/* 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];
-				}
+				printk("%p gpr[%d]->csr=%08x\n",
+					REG_TO_VA(xcp->cp0_epc),
+					MIPSInst_RT(ir), value);
+#endif
+				ctx->sr = value;
+				/* 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];
+			}
+			if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) {
+				return SIGFPE;
 			}
 			break;
+		}
 
-		case bc_op: {
+		case bc_op:{
 			int likely = 0;
 
-			if (regs->cp0_cause & CAUSEF_BD)
+			if (xcp->cp0_cause & CAUSEF_BD)
 				return SIGILL;
 
 #if __mips >= 4
-			cond = ctx-> sr & fpucondbit[MIPSInst_RT(ir) >> 2];
+			cond = ctx->sr & fpucondbit[MIPSInst_RT(ir) >> 2];
 #else
 			cond = ctx->sr & FPU_CSR_COND;
 #endif
@@ -593,16 +440,18 @@
 				return SIGILL;
 			}
 
-			regs->cp0_cause |= CAUSEF_BD;
+			xcp->cp0_cause |= CAUSEF_BD;
 			if (cond) {
-				/* branch taken: emulate dslot instruction */
-				regs->cp0_epc += 4;
-				contpc = REG_TO_VA regs->cp0_epc +
-				                   (MIPSInst_SIMM(ir) << 2);
-
-				err = get_user(ir,
-					(mips_instruction *)regs->cp0_epc);
-				if (err) {
+				/* branch taken: emulate dslot
+				 * instruction
+				 */
+				xcp->cp0_epc += 4;
+				contpc = REG_TO_VA
+					(xcp->cp0_epc +
+					(MIPSInst_SIMM(ir) << 2));
+
+				if (get_user(ir, (mips_instruction *)
+						REG_TO_VA xcp->cp0_epc)) {
 					fpuemuprivate.stats.errors++;
 					return SIGBUS;
 				}
@@ -629,49 +478,50 @@
 				}
 
 				/*
-				 * Single step the non-cp1 instruction in the
-				 * dslot
+				 * Single step the non-cp1
+				 * instruction in the dslot
 				 */
-				return mips_dsemul(regs, ir, contpc);
-			} else {
+				return mips_dsemul(xcp, ir, VA_TO_REG contpc);
+			}
+			else {
 				/* branch not taken */
 				if (likely) {
 					/*
-					 * branch likely nullifies dslot if not
-					 * taken
+					 * branch likely nullifies
+					 * dslot if not taken
 					 */
-					regs->cp0_epc += 4;
+					xcp->cp0_epc += 4;
 					contpc += 4;
 					/*
-					 * else continue & execute dslot as
-					 * normal insn
+					 * else continue & execute
+					 * dslot as normal insn
 					 */
 				}
 			}
 			break;
 		}
 
-		default: {
-			int sig;
-
+		default:
 			if (!(MIPSInst_RS(ir) & 0x10))
 				return SIGILL;
+			{
+				int sig;
 
-			/* a real fpu computation instruction */
-				if ((sig = fpu_emu(regs, ctx, ir)))
+				/* a real fpu computation instruction */
+				if ((sig = fpu_emu(xcp, ctx, ir)))
 					return sig;
 			}
 		}
 		break;
 
 #if __mips >= 4 && __mips != 32
-	case cop1x_op:
-		{
-			int sig;
-			if ((sig = fpux_emu(regs, ctx, ir)))
-				return sig;
-		}
+	case cop1x_op:{
+		int sig;
+
+		if ((sig = fpux_emu(xcp, ctx, ir)))
+			return sig;
 		break;
+	}
 #endif
 
 #if __mips >= 4
@@ -681,7 +531,7 @@
 		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
 		if (((ctx->sr & cond) != 0) != ((MIPSInst_RT(ir) & 1) != 0))
 			return 0;
-		regs->regs[MIPSInst_RD(ir)] = regs->regs[MIPSInst_RS(ir)];
+		xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)];
 		break;
 #endif
 
@@ -690,194 +540,26 @@
 	}
 
 	/* we did it !! */
-	regs->cp0_epc = VA_TO_REG(contpc);
-	regs->cp0_cause &= ~CAUSEF_BD;
+	xcp->cp0_epc = VA_TO_REG(contpc);
+	xcp->cp0_cause &= ~CAUSEF_BD;
 	return 0;
 }
 
 /*
- * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
- * we have to emulate the instruction in a COP1 branch delay slot.  Do
- * not change cp0_epc due to the instruction
- *
- * According to the spec:
- * 1) it shouldnt be a branch :-)
- * 2) it can be a COP instruction :-(
- * 3) if we are tring to run a protected memory space we must take
- *    special care on memory access instructions :-(
- */
-
-/*
- * "Trampoline" return routine to catch exception following
- *  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
-	if (__get_user(epc, &fr->epc)) {		/* Saved EPC */
-		/* This is not a good situation to be in */
-		force_sig(SIGBUS, current);
-
-		return 1;
-	}
-
-	/* Set EPC to return to post-branch instruction */
-	xcp->cp0_epc = epc;
-
-	return 1;
-}
-
-static int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
-	unsigned long cpc)
-{
-	extern asmlinkage void handle_dsemulret(void);
-	mips_instruction *dsemul_insns;
-	struct emuframe *fr;
-	int err;
-
-	if (ir == 0) {		/* a nop is easy */
-		regs->cp0_epc = cpc;
-		regs->cp0_cause &= ~CAUSEF_BD;
-		return 0;
-	}
-#ifdef DSEMUL_TRACE
-	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!!.
-	 *
-	 * Algorithmics used a system call instruction, and
-	 * borrowed that vector.  MIPS/Linux version is a bit
-	 * more heavyweight in the interests of portability and
-	 * multiprocessor support.  We flag the thread for special
-	 * handling in the unaligned access handler and force an
-	 * address error excpetion.
-	 */
-
-	/* 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 (unlikely(err)) {
-		fpuemuprivate.stats.errors++;
-		return SIGBUS;
-	}
-
-	regs->cp0_epc = VA_TO_REG & dsemul_insns[0];
-
-	flush_cache_sigtramp((unsigned long)&fr->adel);
-
-	return SIGILL;		/* force out of emulation loop */
-}
-
-/* 
  * Conversion table from MIPS compare ops 48-63
- * cond = ieee754dp_cmp(x,y,IEEE754_UN);
+ * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
  */
 static const unsigned char cmptab[8] = {
-	0,					/* cmp_0 (sig) cmp_sf */
-	IEEE754_CUN,				/* cmp_un (sig) cmp_ngle */
-	IEEE754_CEQ,				/* cmp_eq (sig) cmp_seq */
-	IEEE754_CEQ | IEEE754_CUN,		/* cmp_ueq (sig) cmp_ngl  */
-	IEEE754_CLT,				/* cmp_olt (sig) cmp_lt */
-	IEEE754_CLT | IEEE754_CUN,		/* cmp_ult (sig) cmp_nge */
-	IEEE754_CLT | IEEE754_CEQ,		/* cmp_ole (sig) cmp_le */
-	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
+	0,			/* cmp_0 (sig) cmp_sf */
+	IEEE754_CUN,		/* cmp_un (sig) cmp_ngle */
+	IEEE754_CEQ,		/* cmp_eq (sig) cmp_seq */
+	IEEE754_CEQ | IEEE754_CUN,	/* cmp_ueq (sig) cmp_ngl  */
+	IEEE754_CLT,		/* cmp_olt (sig) cmp_lt */
+	IEEE754_CLT | IEEE754_CUN,	/* cmp_ult (sig) cmp_nge */
+	IEEE754_CLT | IEEE754_CEQ,	/* cmp_ole (sig) cmp_le */
+	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN,	/* cmp_ule (sig) cmp_ngt */
 };
 
-#define SIFROMREG(si,x)	((si) = ctx->regs[x])
-#define SITOREG(si,x)	(ctx->regs[x] = (int)(si))
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-#define DIFROMREG(di,x)	((di) = ctx->regs[x])
-#define DITOREG(di,x)	(ctx->regs[x] = (di))
-#endif
-
-#define SPFROMREG(sp,x)	((sp).bits = ctx->regs[x])
-#define SPTOREG(sp,x)	(ctx->regs[x] = (sp).bits)
-
-#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)
-#else
-/* Beware: MIPS COP1 doubles are always little_word endian in registers */
-#define DPFROMREG(dp,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)
-#endif
 
 #if __mips >= 4 && __mips != 32
 
@@ -889,17 +571,17 @@
 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; \
-}    
+	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)
 {
@@ -921,233 +603,184 @@
 	return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
 }
 
-DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
-DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
+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(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)
+	mips_instruction ir)
 {
 	unsigned rcsr = 0;	/* resulting csr */
 
 	fpuemuprivate.stats.cp1xops++;
 
 	switch (MIPSInst_FMA_FFMT(ir)) {
-	case s_fmt:		/* 0 */
-		{
-			ieee754sp(*handler) (ieee754sp, ieee754sp,
-					     ieee754sp);
-			ieee754sp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case lwxc1_op:
-				{
-					u32 *va = REG_TO_VA(
-						xcp->regs[MIPSInst_FR(ir)] +
-						xcp->regs[MIPSInst_FT(ir)]);
-					fpureg_t val;
-
-					if (get_user(val, va)) {
-						fpuemuprivate.stats.errors++;
-						return SIGBUS;
-					}
-					if (xcp->cp0_status & ST0_FR) {
-						/* load whole register */
-						ctx->regs[MIPSInst_FD(ir)] =
-						    val;
-					} else if (MIPSInst_FD(ir) & 1) {
-						/* load to m.s. 32 bits */
-#if defined(SINGLE_ONLY_FPU)
-						/* illegal register in single-float mode */
-						return SIGILL;
-#else
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] |=
-						    val << 32;
-#endif
-					} else {
-						/* load to l.s. 32 bits */
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    &= ~0xffffffffLL;
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    |= val;
-					}
-				}
-				break;
+	case s_fmt:{		/* 0 */
 
-			case swxc1_op:
-				{
-					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)];
-					} 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;
+		ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
+		ieee754sp fd, fr, fs, ft;
+		u32 *va;
+		u32 val;
+
+		switch (MIPSInst_FUNC(ir)) {
+		case lwxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
+
+			fpuemuprivate.stats.loads++;
+			if (get_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_FD(ir) & 1) {
+				/* illegal register in single-float
+				 * mode
+				 */
+				return SIGILL;
+			}
 #endif
-					} else {
-						/* store from l.s. 32 bits */
-						val =
-						    ctx->
-						    regs[MIPSInst_FS(ir)];
-					}
-					if (put_user(val, va)) {
-						fpuemuprivate.stats.errors++;
-						return SIGBUS;
-					}
-				}
-				break;
+			SITOREG(val, MIPSInst_FD(ir));
+			break;
 
-			case madd_s_op:
-				handler = fpemu_sp_madd;
-				goto scoptop;
-			case msub_s_op:
-				handler = fpemu_sp_msub;
-				goto scoptop;
-			case nmadd_s_op:
-				handler = fpemu_sp_nmadd;
-				goto scoptop;
-			case nmsub_s_op:
-				handler = fpemu_sp_nmsub;
-				goto scoptop;
+		case swxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
 
-			      scoptop:
-				SPFROMREG(fr, MIPSInst_FR(ir));
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				SPTOREG(fd, MIPSInst_FD(ir));
+			fpuemuprivate.stats.stores++;
+#ifdef SINGLE_ONLY_FPU
+			if (MIPSInst_FS(ir) & 1) {
+				/* illegal register in single-float
+				 * mode
+				 */
+				return SIGILL;
+			}
+#endif
 
-			      copcsr:
-				if (ieee754_cxtest(IEEE754_INEXACT))
-					rcsr |=
-					    FPU_CSR_INE_X | FPU_CSR_INE_S;
-				if (ieee754_cxtest(IEEE754_UNDERFLOW))
-					rcsr |=
-					    FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-				if (ieee754_cxtest(IEEE754_OVERFLOW))
-					rcsr |=
-					    FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-				if (ieee754_cxtest
-				    (IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-
-				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); */
-					return SIGFPE;
-				}
+			SIFROMREG(val, MIPSInst_FS(ir));
+			if (put_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			break;
 
-				break;
+		case madd_s_op:
+			handler = fpemu_sp_madd;
+			goto scoptop;
+		case msub_s_op:
+			handler = fpemu_sp_msub;
+			goto scoptop;
+		case nmadd_s_op:
+			handler = fpemu_sp_nmadd;
+			goto scoptop;
+		case nmsub_s_op:
+			handler = fpemu_sp_nmsub;
+			goto scoptop;
 
-			default:
-				return SIGILL;
+		      scoptop:
+			SPFROMREG(fr, MIPSInst_FR(ir));
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			SPFROMREG(ft, MIPSInst_FT(ir));
+			fd = (*handler) (fr, fs, ft);
+			SPTOREG(fd, MIPSInst_FD(ir));
+
+		      copcsr:
+			if (ieee754_cxtest(IEEE754_INEXACT))
+				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
+			if (ieee754_cxtest(IEEE754_UNDERFLOW))
+				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
+			if (ieee754_cxtest(IEEE754_OVERFLOW))
+				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
+			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+
+			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); */
+				return SIGFPE;
 			}
+
+			break;
+
+		default:
+			return SIGILL;
 		}
 		break;
+	}
 
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt:		/* 1 */
-		{
-			ieee754dp(*handler) (ieee754dp, ieee754dp,
-					     ieee754dp);
-			ieee754dp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case ldxc1_op:
-				{
-					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;
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:{		/* 1 */
+		ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
+		ieee754dp fd, fr, fs, ft;
+		u64 *va;
+		u64 val;
 
-			case sdxc1_op:
-				{
-					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;
-					}
-				}
-				break;
+		switch (MIPSInst_FUNC(ir)) {
+		case ldxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
 
-			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;
+			fpuemuprivate.stats.loads++;
+			if (get_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
+			}
+			DITOREG(val, MIPSInst_FD(ir));
+			break;
 
-			      dcoptop:
-				DPFROMREG(fr, MIPSInst_FR(ir));
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				DPTOREG(fd, MIPSInst_FD(ir));
-				goto copcsr;
+		case sdxc1_op:
+			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
+				xcp->regs[MIPSInst_FT(ir)]);
 
-			default:
-				return SIGILL;
+			fpuemuprivate.stats.stores++;
+			DIFROMREG(val, MIPSInst_FS(ir));
+			if (put_user(val, va)) {
+				fpuemuprivate.stats.errors++;
+				return SIGBUS;
 			}
+			break;
+
+		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;
+
+		      dcoptop:
+			DPFROMREG(fr, MIPSInst_FR(ir));
+			DPFROMREG(fs, MIPSInst_FS(ir));
+			DPFROMREG(ft, MIPSInst_FT(ir));
+			fd = (*handler) (fr, fs, ft);
+			DPTOREG(fd, MIPSInst_FD(ir));
+			goto copcsr;
+
+		default:
+			return SIGILL;
 		}
 		break;
+	}
 #endif
 
 	case 0x7:		/* 7 */
-		{
-			if (MIPSInst_FUNC(ir) != pfetch_op) {
-				return SIGILL;
-			}
-			/* ignore prefx operation */
+		if (MIPSInst_FUNC(ir) != pfetch_op) {
+			return SIGILL;
 		}
+		/* ignore prefx operation */
 		break;
 
 	default:
@@ -1164,7 +797,7 @@
  * Emulate a single COP1 arithmetic instruction.
  */
 static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-                   mips_instruction ir)
+	mips_instruction ir)
 {
 	int rfmt;		/* resulting format */
 	unsigned rcsr = 0;	/* resulting csr */
@@ -1174,49 +807,52 @@
 		ieee754sp s;
 		int w;
 #if __mips64
-		long long l;
+		s64 l;
 #endif
 	} rv;			/* resulting value */
 
 	fpuemuprivate.stats.cp1ops++;
 	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
-	case s_fmt: {		/* 0 */
-		ieee754sp(*handler) ();
+	case s_fmt:{		/* 0 */
+		union {
+			ieee754sp(*b) (ieee754sp, ieee754sp);
+			ieee754sp(*u) (ieee754sp);
+		} handler;
 
 		switch (MIPSInst_FUNC(ir)) {
 			/* binary ops */
 		case fadd_op:
-			handler = ieee754sp_add;
+			handler.b = ieee754sp_add;
 			goto scopbop;
 		case fsub_op:
-			handler = ieee754sp_sub;
+			handler.b = ieee754sp_sub;
 			goto scopbop;
 		case fmul_op:
-			handler = ieee754sp_mul;
+			handler.b = ieee754sp_mul;
 			goto scopbop;
 		case fdiv_op:
-			handler = ieee754sp_div;
+			handler.b = ieee754sp_div;
 			goto scopbop;
 
 			/* unary  ops */
 #if __mips >= 2 || __mips64
 		case fsqrt_op:
-			handler = ieee754sp_sqrt;
+			handler.u = ieee754sp_sqrt;
 			goto scopuop;
 #endif
 #if __mips >= 4 && __mips != 32
 		case frsqrt_op:
-			handler = fpemu_sp_rsqrt;
+			handler.u = fpemu_sp_rsqrt;
 			goto scopuop;
 		case frecip_op:
-			handler = fpemu_sp_recip;
+			handler.u = fpemu_sp_recip;
 			goto scopuop;
 #endif
 #if __mips >= 4
 		case fmovc_op:
 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
 			if (((ctx->sr & cond) != 0) !=
-			    ((MIPSInst_FT(ir) & 1) != 0))
+				((MIPSInst_FT(ir) & 1) != 0))
 				return 0;
 			SPFROMREG(rv.s, MIPSInst_FS(ir));
 			break;
@@ -1232,10 +868,10 @@
 			break;
 #endif
 		case fabs_op:
-			handler = ieee754sp_abs;
+			handler.u = ieee754sp_abs;
 			goto scopuop;
 		case fneg_op:
-			handler = ieee754sp_neg;
+			handler.u = ieee754sp_neg;
 			goto scopuop;
 		case fmov_op:
 			/* an easy one */
@@ -1243,25 +879,25 @@
 			goto copcsr;
 
 			/* binary op on handler */
-scopbop:
+		      scopbop:
 			{
 				ieee754sp fs, ft;
 
 				SPFROMREG(fs, MIPSInst_FS(ir));
 				SPFROMREG(ft, MIPSInst_FT(ir));
 
-				rv.s = (*handler) (fs, ft);
+				rv.s = (*handler.b) (fs, ft);
 				goto copcsr;
 			}
-scopuop:
+		      scopuop:
 			{
 				ieee754sp fs;
 
 				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = (*handler) (fs);
+				rv.s = (*handler.u) (fs);
 				goto copcsr;
 			}
-copcsr:
+		      copcsr:
 			if (ieee754_cxtest(IEEE754_INEXACT))
 				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
 			if (ieee754_cxtest(IEEE754_UNDERFLOW))
@@ -1270,15 +906,14 @@
 				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
 			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
 				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
-			if (ieee754_cxtest
-				(IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-				break;
+			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+			break;
 
-				/* unary conv ops */
+			/* unary conv ops */
 		case fcvts_op:
 			return SIGILL;	/* not defined */
-		case fcvtd_op: {
+		case fcvtd_op:{
 #ifdef SINGLE_ONLY_FPU
 			return SIGILL;	/* not defined */
 #else
@@ -1290,7 +925,7 @@
 			goto copcsr;
 		}
 #endif
-		case fcvtw_op: {
+		case fcvtw_op:{
 			ieee754sp fs;
 
 			SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1303,7 +938,7 @@
 		case fround_op:
 		case ftrunc_op:
 		case fceil_op:
-		case ffloor_op: {
+		case ffloor_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754sp fs;
 
@@ -1317,7 +952,7 @@
 #endif /* __mips >= 2 */
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op: {
+		case fcvtl_op:{
 			ieee754sp fs;
 
 			SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1329,7 +964,7 @@
 		case froundl_op:
 		case ftruncl_op:
 		case fceill_op:
-		case ffloorl_op: {
+		case ffloorl_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754sp fs;
 
@@ -1349,14 +984,17 @@
 
 				SPFROMREG(fs, MIPSInst_FS(ir));
 				SPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]);
+				rv.w = ieee754sp_cmp(fs, ft,
+					cmptab[cmpop & 0x7], cmpop & 0x8);
 				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION))
+				if ((cmpop & 0x8) && ieee754_cxtest
+					(IEEE754_INVALID_OPERATION))
 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
 				else
 					goto copcsr;
 
-			} else {
+			}
+			else {
 				return SIGILL;
 			}
 			break;
@@ -1364,43 +1002,47 @@
 		break;
 	}
 
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt: {
-		ieee754dp(*handler) ();
+#ifndef SINGLE_ONLY_FPU
+	case d_fmt:{
+		union {
+			ieee754dp(*b) (ieee754dp, ieee754dp);
+			ieee754dp(*u) (ieee754dp);
+		} handler;
 
 		switch (MIPSInst_FUNC(ir)) {
 			/* binary ops */
 		case fadd_op:
-			handler = ieee754dp_add;
+			handler.b = ieee754dp_add;
 			goto dcopbop;
 		case fsub_op:
-			handler = ieee754dp_sub;
+			handler.b = ieee754dp_sub;
 			goto dcopbop;
 		case fmul_op:
-			handler = ieee754dp_mul;
+			handler.b = ieee754dp_mul;
 			goto dcopbop;
 		case fdiv_op:
-			handler = ieee754dp_div;
+			handler.b = ieee754dp_div;
 			goto dcopbop;
 
 			/* unary  ops */
 #if __mips >= 2 || __mips64
 		case fsqrt_op:
-			handler = ieee754dp_sqrt;
+			handler.u = ieee754dp_sqrt;
 			goto dcopuop;
 #endif
 #if __mips >= 4 && __mips != 32
 		case frsqrt_op:
-			handler = fpemu_dp_rsqrt;
+			handler.u = fpemu_dp_rsqrt;
 			goto dcopuop;
 		case frecip_op:
-			handler = fpemu_dp_recip;
+			handler.u = fpemu_dp_recip;
 			goto dcopuop;
 #endif
 #if __mips >= 4
 		case fmovc_op:
 			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
-			if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0))
+			if (((ctx->sr & cond) != 0) !=
+				((MIPSInst_FT(ir) & 1) != 0))
 				return 0;
 			DPFROMREG(rv.d, MIPSInst_FS(ir));
 			break;
@@ -1416,11 +1058,11 @@
 			break;
 #endif
 		case fabs_op:
-			handler = ieee754dp_abs;
+			handler.u = ieee754dp_abs;
 			goto dcopuop;
 
 		case fneg_op:
-			handler = ieee754dp_neg;
+			handler.u = ieee754dp_neg;
 			goto dcopuop;
 
 		case fmov_op:
@@ -1429,27 +1071,25 @@
 			goto copcsr;
 
 			/* binary op on handler */
-dcopbop:
-			{
+		      dcopbop:{
 				ieee754dp fs, ft;
 
 				DPFROMREG(fs, MIPSInst_FS(ir));
 				DPFROMREG(ft, MIPSInst_FT(ir));
 
-				rv.d = (*handler) (fs, ft);
+				rv.d = (*handler.b) (fs, ft);
 				goto copcsr;
 			}
-dcopuop:
-			{
+		      dcopuop:{
 				ieee754dp fs;
 
 				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = (*handler) (fs);
+				rv.d = (*handler.u) (fs);
 				goto copcsr;
 			}
 
-		/* unary conv ops */
-		case fcvts_op: {
+			/* unary conv ops */
+		case fcvts_op:{
 			ieee754dp fs;
 
 			DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1460,7 +1100,7 @@
 		case fcvtd_op:
 			return SIGILL;	/* not defined */
 
-		case fcvtw_op: {
+		case fcvtw_op:{
 			ieee754dp fs;
 
 			DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1473,7 +1113,7 @@
 		case fround_op:
 		case ftrunc_op:
 		case fceil_op:
-		case ffloor_op: {
+		case ffloor_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754dp fs;
 
@@ -1487,7 +1127,7 @@
 #endif
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op: {
+		case fcvtl_op:{
 			ieee754dp fs;
 
 			DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1499,7 +1139,7 @@
 		case froundl_op:
 		case ftruncl_op:
 		case fceill_op:
-		case ffloorl_op: {
+		case ffloorl_op:{
 			unsigned int oldrm = ieee754_csr.rm;
 			ieee754dp fs;
 
@@ -1519,33 +1159,42 @@
 
 				DPFROMREG(fs, MIPSInst_FS(ir));
 				DPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]);
+				rv.w = ieee754dp_cmp(fs, ft,
+					cmptab[cmpop & 0x7], cmpop & 0x8);
 				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION))
+				if ((cmpop & 0x8)
+					&&
+					ieee754_cxtest
+					(IEEE754_INVALID_OPERATION))
 					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
 				else
 					goto copcsr;
 
-			} else {
+			}
+			else {
 				return SIGILL;
 			}
 			break;
 		}
 		break;
 	}
-#endif /* !defined(SINGLE_ONLY_FPU) */
+#endif /* ifndef SINGLE_ONLY_FPU */
+
+	case w_fmt:{
+		ieee754sp fs;
 
-	case w_fmt: {
 		switch (MIPSInst_FUNC(ir)) {
 		case fcvts_op:
 			/* convert word to single precision real */
-			rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]);
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.s = ieee754sp_fint(fs.bits);
 			rfmt = s_fmt;
 			goto copcsr;
-#if !defined(SINGLE_ONLY_FPU)
+#ifndef SINGLE_ONLY_FPU
 		case fcvtd_op:
 			/* convert word to double precision real */
-			rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]);
+			SPFROMREG(fs, MIPSInst_FS(ir));
+			rv.d = ieee754dp_fint(fs.bits);
 			rfmt = d_fmt;
 			goto copcsr;
 #endif
@@ -1556,16 +1205,16 @@
 	}
 
 #if __mips64 && !defined(SINGLE_ONLY_FPU)
-	case l_fmt: {
+	case l_fmt:{
 		switch (MIPSInst_FUNC(ir)) {
 		case fcvts_op:
 			/* convert long to single precision real */
-			rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]);
+			rv.s = ieee754sp_flong(ctx->regs[MIPSInst_FS(ir)]);
 			rfmt = s_fmt;
 			goto copcsr;
 		case fcvtd_op:
 			/* convert long to double precision real */
-			rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]);
+			rv.d = ieee754dp_flong(ctx->regs[MIPSInst_FS(ir)]);
 			rfmt = d_fmt;
 			goto copcsr;
 		default:
@@ -1592,11 +1241,11 @@
 		return SIGFPE;
 	}
 
-	/* 
+	/*
 	 * Now we can safely write the result back to the register file.
 	 */
 	switch (rfmt) {
-	case -1: {
+	case -1:{
 #if __mips >= 4
 		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
 #else
@@ -1608,7 +1257,7 @@
 			ctx->sr &= ~cond;
 		break;
 	}
-#if !defined(SINGLE_ONLY_FPU)
+#ifndef SINGLE_ONLY_FPU
 	case d_fmt:
 		DPTOREG(rv.d, MIPSInst_FD(ir));
 		break;
@@ -1631,16 +1280,10 @@
 	return 0;
 }
 
-
-/*
- * Emulate the floating point instruction at EPC, and continue to run until we
- * hit a non-fp instruction, or a backward branch.  This cuts down dramatically
- * on the per instruction exception overhead.
- */
-int fpu_emulator_cop1Handler(struct pt_regs *xcp)
+int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx)
 {
-	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
-	unsigned long oldepc, prevepc;
+	gpreg_t oldepc, prevepc;
 	mips_instruction insn, *insnp;
 	int sig = 0;
 
@@ -1652,9 +1295,10 @@
 		 * 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;
+		insnp = (mips_instruction *) REG_TO_VA xcp->cp0_epc;
+
 		if (verify_area(VERIFY_READ, insnp, 4) ||
-		    __get_user(insn, insnp)) {
+			__get_user(insn, insnp)) {
 			fpuemuprivate.stats.errors++;
 			return SIGBUS;
 		}
@@ -1673,9 +1317,13 @@
 			break;
 		if (sig)
 			break;
-
+#ifdef STANDALONE_EMULATOR
+		if (xcptno == EX_FPE)
+			break;
+#else
 		if (current->need_resched)
 			schedule();
+#endif
 	} while (xcp->cp0_epc > prevepc);
 
 	/* SIGILL indicates a non-fpu instruction */
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_add.c linux-2.4.20-pre7/arch/mips/math-emu/dp_add.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_add.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_add.c	Thu Sep 12 20:01:40 2002
@@ -70,7 +70,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -89,7 +89,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_cmp.c linux-2.4.20-pre7/arch/mips/math-emu/dp_cmp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_cmp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_cmp.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp)
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig)
 {
 	COMPXDP;
 	COMPYDP;
@@ -39,18 +39,18 @@
 	CLEARCX;	/* Even clear inexact flag here */
 
 	if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
-		if (xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+		if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
 			SETCX(IEEE754_INVALID_OPERATION);
 		if (cmp & IEEE754_CUN)
 			return 1;
 		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
+			if (sig && SETCX(IEEE754_INVALID_OPERATION))
 				return ieee754si_xcpt(0, "fcmpf", x);
 		}
 		return 0;
 	} else {
-		long long int vx = x.bits;
-		long long int vy = y.bits;
+		s64 vx = x.bits;
+		s64 vy = y.bits;
 
 		if (vx < 0)
 			vx = -vx ^ DP_SIGN_BIT;
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_div.c linux-2.4.20-pre7/arch/mips/math-emu/dp_div.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_div.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_div.c	Thu Sep 12 20:01:40 2002
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -86,7 +86,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754dp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -126,9 +126,9 @@
 	{
 		/* now the dirty work */
 
-		unsigned long long rm = 0;
+		u64 rm = 0;
 		int re = xe - ye;
-		unsigned long long bm;
+		u64 bm;
 
 		for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
 			if (xm >= ym) {
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_flong.c linux-2.4.20-pre7/arch/mips/math-emu/dp_flong.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_flong.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_flong.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-ieee754dp ieee754dp_flong(long long x)
+ieee754dp ieee754dp_flong(s64 x)
 {
 	COMPXDP;
 
@@ -67,9 +67,9 @@
 	DPNORMRET1(xs, xe, xm, "dp_flong", x);
 }
 
-ieee754dp ieee754dp_fulong(unsigned long long u)
+ieee754dp ieee754dp_fulong(u64 u)
 {
-	if ((long long) u < 0)
+	if ((s64) u < 0)
 		return ieee754dp_add(ieee754dp_1e63(),
 				     ieee754dp_flong(u & ~(1ULL << 63)));
 	return ieee754dp_flong(u);
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_frexp.c linux-2.4.20-pre7/arch/mips/math-emu/dp_frexp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_frexp.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_frexp.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-/* close to ieeep754dp_logb 
+/* close to ieeep754dp_logb
 */
 ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
 {
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_fsp.c linux-2.4.20-pre7/arch/mips/math-emu/dp_fsp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_fsp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_fsp.c	Thu Sep 12 20:01:40 2002
@@ -44,7 +44,7 @@
 	case IEEE754_CLASS_QNAN:
 		return ieee754dp_nanxcpt(builddp(xs,
 						 DP_EMAX + 1 + DP_EBIAS,
-						 ((unsigned long long) xm
+						 ((u64) xm
 						  << (DP_MBITS -
 						      SP_MBITS))), "fsp",
 					 x);
@@ -70,5 +70,5 @@
 	xm &= ~SP_HIDDEN_BIT;
 
 	return builddp(xs, xe + DP_EBIAS,
-		       (unsigned long long) xm << (DP_MBITS - SP_MBITS));
+		       (u64) xm << (DP_MBITS - SP_MBITS));
 }
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_modf.c linux-2.4.20-pre7/arch/mips/math-emu/dp_modf.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_modf.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_modf.c	Thu Sep 12 20:01:40 2002
@@ -59,7 +59,7 @@
 		*ip = x;
 		return ieee754dp_zero(xs);
 	}
-	/* generate ipart mantissa by clearing bottom bits 
+	/* generate ipart mantissa by clearing bottom bits
 	 */
 	*ip = builddp(xs, xe + DP_EBIAS,
 		      ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_mul.c linux-2.4.20-pre7/arch/mips/math-emu/dp_mul.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_mul.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_mul.c	Thu Sep 12 20:01:40 2002
@@ -111,7 +111,7 @@
 	{
 		int re = xe + ye;
 		int rs = xs ^ ys;
-		unsigned long long rm;
+		u64 rm;
 
 		/* shunt to top of word */
 		xm <<= 64 - (DP_MBITS + 1);
@@ -121,23 +121,23 @@
 		 */
 
 		/* 32 * 32 => 64 */
-#define DPXMULT(x,y)	((unsigned long long)(x) * (unsigned long long)y)
+#define DPXMULT(x,y)	((u64)(x) * (u64)y)
 
 		{
 			unsigned lxm = xm;
 			unsigned hxm = xm >> 32;
 			unsigned lym = ym;
 			unsigned hym = ym >> 32;
-			unsigned long long lrm;
-			unsigned long long hrm;
+			u64 lrm;
+			u64 hrm;
 
 			lrm = DPXMULT(lxm, lym);
 			hrm = DPXMULT(hxm, hym);
 
 			{
-				unsigned long long t = DPXMULT(lxm, hym);
+				u64 t = DPXMULT(lxm, hym);
 				{
-					unsigned long long at =
+					u64 at =
 					    lrm + (t << 32);
 					hrm += at < lrm;
 					lrm = at;
@@ -146,9 +146,9 @@
 			}
 
 			{
-				unsigned long long t = DPXMULT(hxm, lym);
+				u64 t = DPXMULT(hxm, lym);
 				{
-					unsigned long long at =
+					u64 at =
 					    lrm + (t << 32);
 					hrm += at < lrm;
 					lrm = at;
@@ -161,7 +161,7 @@
 		/*
 		 * sticky shift down to normal rounding precision
 		 */
-		if ((signed long long) rm < 0) {
+		if ((s64) rm < 0) {
 			rm =
 			    (rm >> (64 - (DP_MBITS + 1 + 3))) |
 			    ((rm << (DP_MBITS + 1 + 3)) != 0);
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_sqrt.c linux-2.4.20-pre7/arch/mips/math-emu/dp_sqrt.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_sqrt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_sqrt.c	Thu Sep 12 20:01:40 2002
@@ -99,7 +99,7 @@
 	yh = y.bits >> 32;
 	yh = (yh >> 1) + 0x1ff80000;
 	yh = yh - table[(yh >> 15) & 31];
-	y.bits = ((unsigned long long) yh << 32) | (y.bits & 0xffffffff);
+	y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff);
 
 	/* Heron's rule once with correction to improve to ~18 sig. bits */
 	/* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_sub.c linux-2.4.20-pre7/arch/mips/math-emu/dp_sub.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_sub.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_sub.c	Thu Sep 12 20:01:40 2002
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -88,7 +88,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -180,7 +180,7 @@
 				return ieee754dp_zero(0);	/* other round modes   => sign = 1 */
 		}
 
-		/* normalize to rounding precision 
+		/* normalize to rounding precision
 		 */
 		while ((xm >> (DP_MBITS + 3)) == 0) {
 			xm <<= 1;
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_tint.c linux-2.4.20-pre7/arch/mips/math-emu/dp_tint.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_tint.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_tint.c	Thu Sep 12 20:01:40 2002
@@ -49,10 +49,7 @@
 	case IEEE754_CLASS_NORM:
 		break;
 	}
-	if (xe >= 31) {
-		/* look for valid corner case */
-		if (xe == 31 && xs && xm == DP_HIDDEN_BIT)
-			return -2147483648;
+	if (xe > 31) {
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -62,7 +59,7 @@
 	if (xe > DP_MBITS) {
 		xm <<= xe - DP_MBITS;
 	} else if (xe < DP_MBITS) {
-		unsigned long long residue;
+		u64 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -98,7 +95,8 @@
 				xm++;
 			break;
 		}
-		if ((xm >> 31) != 0) {
+		/* look for valid corner case 0x80000000 */
+		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
 			/* This can happen after rounding */
 			SETCX(IEEE754_INVALID_OPERATION);
 			return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dp_tlong.c linux-2.4.20-pre7/arch/mips/math-emu/dp_tlong.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dp_tlong.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/dp_tlong.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754dp.h"
 
-long long ieee754dp_tlong(ieee754dp x)
+s64 ieee754dp_tlong(ieee754dp x)
 {
 	COMPXDP;
 
@@ -49,9 +49,9 @@
 		break;
 	}
 	if (xe >= 63) {
-		/* look for valid corner case */ 
+		/* look for valid corner case */
 		if (xe == 63 && xs && xm == DP_HIDDEN_BIT)
-			return -9223372036854775808LL;
+			return -0x8000000000000000LL;
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -61,7 +61,7 @@
 	if (xe > DP_MBITS) {
 		xm <<= xe - DP_MBITS;
 	} else if (xe < DP_MBITS) {
-		unsigned long long residue;
+		u64 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -73,7 +73,11 @@
 			xm = 0;
 		}
 		else {
-			residue = xm << (64 - DP_MBITS + xe);
+			/* Shifting a u64 64 times does not work,
+			* so we do it in two steps. Be aware that xe
+			* may be -1 */
+			residue = xm << (xe + 1);
+			residue <<= 63 - DP_MBITS;
 			round = (residue >> 63) != 0;
 			sticky = (residue << 1) != 0;
 			xm >>= DP_MBITS - xe;
@@ -110,14 +114,14 @@
 }
 
 
-unsigned long long ieee754dp_tulong(ieee754dp x)
+u64 ieee754dp_tulong(ieee754dp x)
 {
 	ieee754dp hb = ieee754dp_1e63();
 
 	/* what if x < 0 ?? */
 	if (ieee754dp_lt(x, hb))
-		return (unsigned long long) ieee754dp_tlong(x);
+		return (u64) ieee754dp_tlong(x);
 
-	return (unsigned long long) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
+	return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
 	    (1ULL << 63);
 }
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dsemul.c linux-2.4.20-pre7/arch/mips/math-emu/dsemul.c
--- linux-2.4.20-pre6/arch/mips/math-emu/dsemul.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/math-emu/dsemul.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,173 @@
+#include <linux/compiler.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/byteorder.h>
+#include <asm/cpu.h>
+#include <asm/inst.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+
+#include <asm/fpu_emulator.h>
+
+#include "ieee754.h"
+#include "dsemul.h"
+
+/* Strap kernel emulator for full MIPS IV emulation */
+
+#ifdef __mips
+#undef __mips
+#endif
+#define __mips 4
+
+extern struct mips_fpu_emulator_private fpuemuprivate;
+
+
+/*
+ * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
+ * we have to emulate the instruction in a COP1 branch delay slot.  Do
+ * not change cp0_epc due to the instruction
+ *
+ * According to the spec:
+ * 1) it shouldnt be a branch :-)
+ * 2) it can be a COP instruction :-(
+ * 3) if we are tring to run a protected memory space we must take
+ *    special care on memory access instructions :-(
+ */
+
+/*
+ * "Trampoline" return routine to catch exception following
+ *  execution of delay-slot instruction execution.
+ */
+
+struct emuframe {
+	mips_instruction	emul;
+	mips_instruction	badinst;
+	mips_instruction	cookie;
+	gpreg_t			epc;
+};
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
+{
+	extern asmlinkage void handle_dsemulret(void);
+	mips_instruction *dsemul_insns;
+	struct emuframe *fr;
+	int err;
+
+	if (ir == 0) {		/* a nop is easy */
+		regs->cp0_epc = cpc;
+		regs->cp0_cause &= ~CAUSEF_BD;
+		return 0;
+	}
+#ifdef DSEMUL_TRACE
+	printk("dsemul %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!!.
+	 *
+	 * Algorithmics used a system call instruction, and
+	 * borrowed that vector.  MIPS/Linux version is a bit
+	 * more heavyweight in the interests of portability and
+	 * multiprocessor support.  For Linux we generate a
+	 * an unaligned access and force an address error exception.
+	 *
+	 * For embedded systems (stand-alone) we prefer to use a
+	 * non-existing CP1 instruction. This prevents us from emulating
+	 * branches, but gives us a cleaner interface to the exception
+	 * handler (single entry point).
+	 */
+
+	/* Ensure that the two instructions are in the same cache line */
+	dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+	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, &fr->emul);
+	err |= __put_user((mips_instruction)BADINST, &fr->badinst);
+	err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
+	err |= __put_user(cpc, &fr->epc);
+
+	if (unlikely(err)) {
+		fpuemuprivate.stats.errors++;
+		return SIGBUS;
+	}
+
+	regs->cp0_epc = VA_TO_REG & fr->emul;
+
+	flush_cache_sigtramp((unsigned long)&fr->badinst);
+
+	return SIGILL;		/* force out of emulation loop */
+}
+
+int do_dsemulret(struct pt_regs *xcp)
+{
+	struct emuframe *fr;
+	gpreg_t 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 BADINST?
+	 *  - Is the following memory word the BD_COOKIE?
+	 */
+	err = __get_user(insn, &fr->badinst);
+	err |= __get_user(cookie, &fr->cookie);
+
+	if (unlikely(err || (insn != BADINST) || (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("dsemulret\n");
+#endif
+	if (__get_user(epc, &fr->epc)) {		/* Saved EPC */
+		/* This is not a good situation to be in */
+		force_sig(SIGBUS, current);
+
+		return 0;
+	}
+
+	/* Set EPC to return to post-branch instruction */
+	xcp->cp0_epc = epc;
+
+	return 1;
+}
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/dsemul.h linux-2.4.20-pre7/arch/mips/math-emu/dsemul.h
--- linux-2.4.20-pre6/arch/mips/math-emu/dsemul.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/math-emu/dsemul.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,23 @@
+typedef long gpreg_t;
+typedef void *vaddr_t;
+
+#define REG_TO_VA (vaddr_t)
+#define VA_TO_REG (gpreg_t)
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
+int do_dsemulret(struct pt_regs *xcp);
+
+/* Instruction which will always cause an address error */
+#define AdELOAD 0x8c000001	/* lw $0,1($0) */
+/* Instruction which will plainly cause a CP1 exception when FPU is disabled */
+#define CP1UNDEF 0x44400001    /* cfc1 $0,$0 undef  */
+
+/* Instruction inserted following the badinst to further tag the sequence */
+#define BD_COOKIE 0x0000bd36 /* tne $0,$0 with baggage */
+
+/* Setup which instruction to use for trampoline */
+#ifdef STANDALONE_EMULATOR
+#define BADINST CP1UNDEF
+#else
+#define BADINST AdELOAD
+#endif
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754.c linux-2.4.20-pre7/arch/mips/math-emu/ieee754.c
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754.c	Thu Sep 12 20:01:40 2002
@@ -3,7 +3,7 @@
  *
  * BUGS
  * not much dp done
- * doesnt generate IEEE754_INEXACT
+ * doesn't generate IEEE754_INEXACT
  *
  */
 /*
@@ -50,7 +50,7 @@
 	"SNaN",
 };
 
-/* the control status register 
+/* the control status register
 */
 struct ieee754_csr ieee754_csr;
 
@@ -123,7 +123,7 @@
 	return ax.rv.si;
 }
 
-long long ieee754di_xcpt(long long r, const char *op, ...)
+s64 ieee754di_xcpt(s64 r, const char *op, ...)
 {
 	struct ieee754xctx ax;
 
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754.h linux-2.4.20-pre7/arch/mips/math-emu/ieee754.h
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754.h	Thu Sep 12 20:01:40 2002
@@ -26,7 +26,7 @@
 
 /**************************************************************************
  *  Nov 7, 2000
- *  Modification to allow integration with Linux kernel 
+ *  Modification to allow integration with Linux kernel
  *
  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
  *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
@@ -36,8 +36,8 @@
 /* Going from Algorithmics to Linux native environment, add this */
 #include <linux/types.h>
 
-/* 
- * Not very pretty, but the Linux kernel's normal va_list definition 
+/*
+ * Not very pretty, but the Linux kernel's normal va_list definition
  * does not allow it to be used as a structure element, as it is here.
  */
 #ifndef _STDARG_H
@@ -71,18 +71,18 @@
 typedef union _ieee754dp {
 	struct ieee754dp_konst oparts;
 	struct {
-		unsigned long long mant:52;
+		u64 mant:52;
 		unsigned int bexp:11;
 		unsigned int sign:1;
 	} parts;
-	unsigned long long bits;
+	u64 bits;
 	double d;
 } ieee754dp;
 
 typedef union _ieee754sp {
 	struct ieee754sp_konst parts;
 	float f;
-	unsigned long bits;
+	u32 bits;
 } ieee754sp;
 #endif
 
@@ -98,10 +98,10 @@
 	struct {
 		unsigned int sign:1;
 		unsigned int bexp:11;
-		unsigned long long mant:52;
+		u64 mant:52;
 	} parts;
 	double d;
-	unsigned long long bits;
+	u64 bits;
 } ieee754dp;
 
 struct ieee754sp_konst {
@@ -113,7 +113,7 @@
 typedef union _ieee754sp {
 	struct ieee754sp_konst parts;
 	float f;
-	unsigned long bits;
+	u32 bits;
 } ieee754sp;
 #endif
 
@@ -138,16 +138,16 @@
 
 ieee754sp ieee754sp_fint(int x);
 ieee754sp ieee754sp_funs(unsigned x);
-ieee754sp ieee754sp_flong(long long x);
-ieee754sp ieee754sp_fulong(unsigned long long x);
+ieee754sp ieee754sp_flong(s64 x);
+ieee754sp ieee754sp_fulong(u64 x);
 ieee754sp ieee754sp_fdp(ieee754dp x);
 
 int ieee754sp_tint(ieee754sp x);
 unsigned int ieee754sp_tuns(ieee754sp x);
-long long ieee754sp_tlong(ieee754sp x);
-unsigned long long ieee754sp_tulong(ieee754sp x);
+s64 ieee754sp_tlong(ieee754sp x);
+u64 ieee754sp_tulong(ieee754sp x);
 
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop);
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
 /*
  * basic sp math
  */
@@ -179,14 +179,14 @@
 ieee754dp ieee754dp_neg(ieee754dp x);
 ieee754dp ieee754dp_scalb(ieee754dp x, int);
 
-/* return exponent as integer in floating point format 
+/* return exponent as integer in floating point format
  */
 ieee754dp ieee754dp_logb(ieee754dp x);
 
 ieee754dp ieee754dp_fint(int x);
 ieee754dp ieee754dp_funs(unsigned x);
-ieee754dp ieee754dp_flong(long long x);
-ieee754dp ieee754dp_fulong(unsigned long long x);
+ieee754dp ieee754dp_flong(s64 x);
+ieee754dp ieee754dp_fulong(u64 x);
 ieee754dp ieee754dp_fsp(ieee754sp x);
 
 ieee754dp ieee754dp_ceil(ieee754dp x);
@@ -195,10 +195,10 @@
 
 int ieee754dp_tint(ieee754dp x);
 unsigned int ieee754dp_tuns(ieee754dp x);
-long long ieee754dp_tlong(ieee754dp x);
-unsigned long long ieee754dp_tulong(ieee754dp x);
+s64 ieee754dp_tlong(ieee754dp x);
+u64 ieee754dp_tulong(ieee754dp x);
 
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop);
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
 /*
  * basic sp math
  */
@@ -214,7 +214,7 @@
 
 
 
-/* 5 types of floating point number 
+/* 5 types of floating point number
 */
 #define IEEE754_CLASS_NORM	0x00
 #define IEEE754_CLASS_ZERO	0x01
@@ -238,7 +238,7 @@
 #define IEEE754_CGT	0x04
 #define IEEE754_CUN	0x08
 
-/* rounding mode 
+/* rounding mode
 */
 #define IEEE754_RN	0	/* round to nearest */
 #define IEEE754_RZ	1	/* round toward zero  */
@@ -253,65 +253,65 @@
 */
 static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CEQ);
+	return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
 {
 	return ieee754sp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
+			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
 }
 
 static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CLT);
+	return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
 }
 
 static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
+	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CGT);
+	return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
 }
 
 
 static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
 {
-	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
+	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CEQ);
+	return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
 {
 	return ieee754dp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
+			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
 }
 
 static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CLT);
+	return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
 }
 
 static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
+	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
 }
 
 static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CGT);
+	return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
 }
 
 static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
 {
-	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
+	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
 }
 
 
@@ -321,7 +321,7 @@
 char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
 
 
-/* the control status register 
+/* the control status register
 */
 struct ieee754_csr {
 	unsigned pad:13;
@@ -350,7 +350,7 @@
 	return (ieee754_csr.cx);
 }
 
-/* test for current exception condition 
+/* test for current exception condition
  */
 static __inline int ieee754_cxtest(unsigned n)
 {
@@ -372,7 +372,7 @@
 	return (ieee754_csr.sx = 0);
 }
 
-/* test for sticky exception condition 
+/* test for sticky exception condition
  */
 static __inline int ieee754_sxtest(unsigned n)
 {
@@ -450,13 +450,13 @@
 #define ieee754sp_1e63() \
   (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
 
-/* indefinite integer value 
+/* indefinite integer value
 */
 #define ieee754si_indef()	INT_MAX
 #ifdef LONG_LONG_MAX
 #define ieee754di_indef()	LONG_LONG_MAX
 #else
-#define ieee754di_indef()	((long long)(~0ULL>>1))
+#define ieee754di_indef()	((s64)(~0ULL>>1))
 #endif
 
 /* IEEE exception context, passed to handler */
@@ -470,7 +470,7 @@
 		ieee754xp xp;	/* extended precision */
 #endif
 		int si;		/* standard signed integer (32bits) */
-		long long di;	/* extended signed integer (64bits) */
+		s64 di;		/* extended signed integer (64bits) */
 	} rv;			/* default result format implied by op */
 	va_list ap;
 };
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754d.c linux-2.4.20-pre7/arch/mips/math-emu/ieee754d.c
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754d.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754d.c	Thu Sep 12 20:01:40 2002
@@ -20,7 +20,7 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  *  Nov 7, 2000
- *  Modified to build and operate in Linux kernel environment. 
+ *  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.
@@ -39,12 +39,12 @@
 #define SP_EMAX		127
 #define SP_FBITS	23
 
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
+#define DP_MBIT(x)	((u64)1 << (x))
 #define DP_HIDDEN_BIT	DP_MBIT(DP_FBITS)
 #define DP_SIGN_BIT	DP_MBIT(63)
 
 
-#define SP_MBIT(x)	((unsigned long)1 << (x))
+#define SP_MBIT(x)	((u32)1 << (x))
 #define SP_HIDDEN_BIT	SP_MBIT(SP_FBITS)
 #define SP_SIGN_BIT	SP_MBIT(31)
 
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754dp.c linux-2.4.20-pre7/arch/mips/math-emu/ieee754dp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754dp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754dp.c	Thu Sep 12 20:01:40 2002
@@ -98,9 +98,9 @@
 }
 
 
-static unsigned long long get_rounding(int sn, unsigned long long xm)
+static u64 get_rounding(int sn, u64 xm)
 {
-	/* inexact must round of 3 bits 
+	/* inexact must round of 3 bits
 	 */
 	if (xm & (DP_MBIT(3) - 1)) {
 		switch (ieee754_csr.rm) {
@@ -129,7 +129,7 @@
  * xe is an unbiased exponent
  * xm is 3bit extended precision value.
  */
-ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm)
+ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
 {
 	assert(xm);		/* we dont gen exact zeros (probably should) */
 
@@ -174,7 +174,7 @@
 			xe++;
 		}
 		else {
-			/* sticky right shift es bits 
+			/* sticky right shift es bits
 			 */
 			xm = XDPSRS(xm, es);
 			xe += es;
@@ -188,10 +188,10 @@
 			SETCX(IEEE754_UNDERFLOW);
 		}
 
-		/* inexact must round of 3 bits 
+		/* inexact must round of 3 bits
 		 */
 		xm = get_rounding(sn, xm);
-		/* adjust exponent for rounding add overflowing 
+		/* adjust exponent for rounding add overflowing
 		 */
 		if (xm >> (DP_MBITS + 3 + 1)) {
 			/* add causes mantissa overflow */
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754dp.h linux-2.4.20-pre7/arch/mips/math-emu/ieee754dp.h
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754dp.h	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754dp.h	Thu Sep 12 20:01:40 2002
@@ -1,4 +1,4 @@
-/* 
+/*
  * IEEE754 floating point
  * double precision internal header file
  */
@@ -46,7 +46,7 @@
 #define DPDNORMX	DPDNORMx(xm,xe)
 #define DPDNORMY	DPDNORMx(ym,ye)
 
-static __inline ieee754dp builddp(int s, int bx, unsigned long long m)
+static __inline ieee754dp builddp(int s, int bx, u64 m)
 {
 	ieee754dp r;
 
@@ -64,11 +64,11 @@
 extern int ieee754dp_isnan(ieee754dp);
 extern int ieee754dp_issnan(ieee754dp);
 extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
 extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
 extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
 extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
-extern ieee754dp ieee754dp_format(int, int, unsigned long long);
+extern ieee754dp ieee754dp_format(int, int, u64);
 
 
 #define DPNORMRET2(s,e,m,name,a0,a1) \
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754int.h linux-2.4.20-pre7/arch/mips/math-emu/ieee754int.h
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754int.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754int.h	Thu Sep 12 20:01:40 2002
@@ -1,4 +1,4 @@
-/* 
+/*
  * IEEE754 floating point
  * common internal header file
  */
@@ -38,11 +38,11 @@
 #define SP_EMAX		127
 #define SP_MBITS	23
 
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
+#define DP_MBIT(x)	((u64)1 << (x))
 #define DP_HIDDEN_BIT	DP_MBIT(DP_MBITS)
 #define DP_SIGN_BIT	DP_MBIT(63)
 
-#define SP_MBIT(x)	((unsigned long)1 << (x))
+#define SP_MBIT(x)	((u32)1 << (x))
 #define SP_HIDDEN_BIT	SP_MBIT(SP_MBITS)
 #define SP_SIGN_BIT	SP_MBIT(31)
 
@@ -102,10 +102,10 @@
 
 
 #define COMPXDP \
-unsigned long long xm; int xe; int xs; int xc
+u64 xm; int xe; int xs; int xc
 
 #define COMPYDP \
-unsigned long long ym; int ye; int ys; int yc
+u64 ym; int ye; int ys; int yc
 
 #define EXPLODEDP(v,vc,vs,ve,vm) \
 {\
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754sp.c linux-2.4.20-pre7/arch/mips/math-emu/ieee754sp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754sp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754sp.c	Thu Sep 12 20:01:40 2002
@@ -101,7 +101,7 @@
 
 static unsigned get_rounding(int sn, unsigned xm)
 {
-	/* inexact must round of 3 bits 
+	/* inexact must round of 3 bits
 	 */
 	if (xm & (SP_MBIT(3) - 1)) {
 		switch (ieee754_csr.rm) {
@@ -175,7 +175,7 @@
 			xe++;
 		}
 		else {
-			/* sticky right shift es bits 
+			/* sticky right shift es bits
 			 */
 			SPXSRSXn(es);
 			assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
@@ -188,10 +188,10 @@
 			SETCX(IEEE754_UNDERFLOW);
 		}
 
-		/* inexact must round of 3 bits 
+		/* inexact must round of 3 bits
 		 */
 		xm = get_rounding(sn, xm);
-		/* adjust exponent for rounding add overflowing 
+		/* adjust exponent for rounding add overflowing
 		 */
 		if (xm >> (SP_MBITS + 1 + 3)) {
 			/* add causes mantissa overflow */
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754sp.h linux-2.4.20-pre7/arch/mips/math-emu/ieee754sp.h
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754sp.h	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754sp.h	Thu Sep 12 20:01:40 2002
@@ -1,4 +1,4 @@
-/* 
+/*
  * IEEE754 floating point
  * double precision internal header file
  */
@@ -70,7 +70,7 @@
 extern int ieee754sp_isnan(ieee754sp);
 extern int ieee754sp_issnan(ieee754sp);
 extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
 extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
 extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
 extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/ieee754xcpt.c linux-2.4.20-pre7/arch/mips/math-emu/ieee754xcpt.c
--- linux-2.4.20-pre6/arch/mips/math-emu/ieee754xcpt.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/ieee754xcpt.c	Thu Sep 12 20:01:40 2002
@@ -23,7 +23,7 @@
 
 /**************************************************************************
  *  Nov 7, 2000
- *  Added preprocessor hacks to map to Linux kernel diagnostics. 
+ *  Added preprocessor hacks to map to Linux kernel diagnostics.
  *
  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/kernel_linkage.c linux-2.4.20-pre7/arch/mips/math-emu/kernel_linkage.c
--- linux-2.4.20-pre6/arch/mips/math-emu/kernel_linkage.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/kernel_linkage.c	Thu Sep 12 20:01:40 2002
@@ -39,7 +39,7 @@
 {
 	static int first = 1;
 	int i;
- 
+
 	if (first) {
 		first = 0;
 		printk("Algorithmics/MIPS FPU Emulator v1.5\n");
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_add.c linux-2.4.20-pre7/arch/mips/math-emu/sp_add.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_add.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_add.c	Thu Sep 12 20:01:40 2002
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -88,7 +88,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_cmp.c linux-2.4.20-pre7/arch/mips/math-emu/sp_cmp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_cmp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_cmp.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp)
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig)
 {
 	COMPXSP;
 	COMPYSP;
@@ -39,12 +39,12 @@
 	CLEARCX;	/* Even clear inexact flag here */
 
 	if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
-		if (xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+		if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
 			SETCX(IEEE754_INVALID_OPERATION);
 		if (cmp & IEEE754_CUN)
 			return 1;
 		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
+			if (sig && SETCX(IEEE754_INVALID_OPERATION))
 				return ieee754si_xcpt(0, "fcmpf", x);
 		}
 		return 0;
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_div.c linux-2.4.20-pre7/arch/mips/math-emu/sp_div.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_div.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_div.c	Thu Sep 12 20:01:40 2002
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Infinity handeling 
+		/* Infinity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -86,7 +86,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return ieee754sp_inf(xs ^ ys);
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_fdp.c linux-2.4.20-pre7/arch/mips/math-emu/sp_fdp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_fdp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_fdp.c	Thu Sep 12 20:01:40 2002
@@ -43,7 +43,7 @@
 		SETCX(IEEE754_INVALID_OPERATION);
 		return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
 	case IEEE754_CLASS_QNAN:
-		nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (unsigned long)
+		nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
 				(xm >> (DP_MBITS - SP_MBITS)));
 		if (!ieee754sp_isnan(nan))
 			nan = ieee754sp_indef();
@@ -57,7 +57,7 @@
 		SETCX(IEEE754_UNDERFLOW);
 		SETCX(IEEE754_INEXACT);
 		if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
-		    (ieee754_csr.rm == IEEE754_RD && 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:
@@ -65,9 +65,9 @@
 	}
 
 	{
-		unsigned long rm;
+		u32 rm;
 
-		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift 
+		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift
 		 */
 		rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
 		    ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_fint.c linux-2.4.20-pre7/arch/mips/math-emu/sp_fint.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_fint.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_fint.c	Thu Sep 12 20:01:40 2002
@@ -52,13 +52,13 @@
 	xe = SP_MBITS + 3;
 
 	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
+		/* shunt out overflow bits
 		 */
 		while (xm >> (SP_MBITS + 1 + 3)) {
 			SPXSRSX1();
 		}
 	} else {
-		/* normalize in grs extended single precision 
+		/* normalize in grs extended single precision
 		 */
 		while ((xm >> (SP_MBITS + 3)) == 0) {
 			xm <<= 1;
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_flong.c linux-2.4.20-pre7/arch/mips/math-emu/sp_flong.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_flong.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_flong.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-ieee754sp ieee754sp_flong(long long x)
+ieee754sp ieee754sp_flong(s64 x)
 {
 	COMPXDP;		/* <--- need 64-bit mantissa temp */
 
@@ -52,7 +52,7 @@
 	xe = SP_MBITS + 3;
 
 	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
+		/* shunt out overflow bits
 		 */
 		while (xm >> (SP_MBITS + 1 + 3)) {
 			SPXSRSX1();
@@ -68,9 +68,9 @@
 }
 
 
-ieee754sp ieee754sp_fulong(unsigned long long u)
+ieee754sp ieee754sp_fulong(u64 u)
 {
-	if ((long long) u < 0)
+	if ((s64) u < 0)
 		return ieee754sp_add(ieee754sp_1e63(),
 				     ieee754sp_flong(u & ~(1ULL << 63)));
 	return ieee754sp_flong(u);
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_frexp.c linux-2.4.20-pre7/arch/mips/math-emu/sp_frexp.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_frexp.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_frexp.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-/* close to ieeep754sp_logb 
+/* close to ieeep754sp_logb
 */
 ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
 {
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_modf.c linux-2.4.20-pre7/arch/mips/math-emu/sp_modf.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_modf.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_modf.c	Thu Sep 12 20:01:40 2002
@@ -59,7 +59,7 @@
 		*ip = x;
 		return ieee754sp_zero(xs);
 	}
-	/* generate ipart mantissa by clearing bottom bits 
+	/* generate ipart mantissa by clearing bottom bits
 	 */
 	*ip = buildsp(xs, xe + SP_EBIAS,
 		      ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_sub.c linux-2.4.20-pre7/arch/mips/math-emu/sp_sub.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_sub.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_sub.c	Thu Sep 12 20:01:40 2002
@@ -69,7 +69,7 @@
 		return x;
 
 
-		/* Inifity handeling 
+		/* Inifity handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
@@ -88,7 +88,7 @@
 	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
 		return x;
 
-		/* Zero handeling 
+		/* Zero handeling
 		 */
 
 	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
@@ -173,7 +173,7 @@
 			else
 				return ieee754sp_zero(0);	/* other round modes   => sign = 1 */
 
-		/* normalize to rounding precision 
+		/* normalize to rounding precision
 		 */
 		while ((xm >> (SP_MBITS + 3)) == 0) {
 			xm <<= 1;
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_tint.c linux-2.4.20-pre7/arch/mips/math-emu/sp_tint.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_tint.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_tint.c	Thu Sep 12 20:01:40 2002
@@ -52,7 +52,7 @@
 	if (xe >= 31) {
 		/* look for valid corner case */
 		if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
-			return -2147483648;
+			return -0x80000000;
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -62,7 +62,7 @@
 	if (xe > SP_MBITS) {
 		xm <<= xe - SP_MBITS;
 	} else {
-		unsigned long residue;
+		u32 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -74,7 +74,11 @@
 			xm = 0;
 		}
 		else {
-			residue = xm << (32 - SP_MBITS + xe);
+			/* Shifting a u32 32 times does not work,
+			* so we do it in two steps. Be aware that xe
+			* may be -1 */
+			residue = xm << (xe + 1);
+			residue <<= 31 - SP_MBITS;
 			round = (residue >> 31) != 0;
 			sticky = (residue << 1) != 0;
 			xm >>= SP_MBITS - xe;
diff -urN linux-2.4.20-pre6/arch/mips/math-emu/sp_tlong.c linux-2.4.20-pre7/arch/mips/math-emu/sp_tlong.c
--- linux-2.4.20-pre6/arch/mips/math-emu/sp_tlong.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/math-emu/sp_tlong.c	Thu Sep 12 20:01:40 2002
@@ -27,7 +27,7 @@
 
 #include "ieee754sp.h"
 
-long long ieee754sp_tlong(ieee754sp x)
+s64 ieee754sp_tlong(ieee754sp x)
 {
 	COMPXDP;		/* <-- need 64-bit mantissa tmp */
 
@@ -51,7 +51,7 @@
 	if (xe >= 63) {
 		/* look for valid corner case */
 		if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
-			return -9223372036854775808LL;
+			return -0x8000000000000000LL;
 		/* Set invalid. We will only use overflow for floating
 		   point overflow */
 		SETCX(IEEE754_INVALID_OPERATION);
@@ -61,7 +61,7 @@
 	if (xe > SP_MBITS) {
 		xm <<= xe - SP_MBITS;
 	} else if (xe < SP_MBITS) {
-		unsigned long residue;
+		u32 residue;
 		int round;
 		int sticky;
 		int odd;
@@ -98,7 +98,7 @@
 		if ((xm >> 63) != 0) {
 			/* This can happen after rounding */
 			SETCX(IEEE754_INVALID_OPERATION);
-			return ieee754si_xcpt(ieee754di_indef(), "sp_tlong", x);
+			return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
 		}
 		if (round || sticky)
 			SETCX(IEEE754_INEXACT);
@@ -110,14 +110,14 @@
 }
 
 
-unsigned long long ieee754sp_tulong(ieee754sp x)
+u64 ieee754sp_tulong(ieee754sp x)
 {
 	ieee754sp hb = ieee754sp_1e63();
 
 	/* what if x < 0 ?? */
 	if (ieee754sp_lt(x, hb))
-		return (unsigned long long) ieee754sp_tlong(x);
+		return (u64) ieee754sp_tlong(x);
 
-	return (unsigned long long) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
+	return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
 	    (1ULL << 63);
 }
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/atlas/Makefile linux-2.4.20-pre7/arch/mips/mips-boards/atlas/Makefile
--- linux-2.4.20-pre6/arch/mips/mips-boards/atlas/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/atlas/Makefile	Thu Sep 12 20:01:40 2002
@@ -7,12 +7,12 @@
 # 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.
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/atlas/atlas_int.c linux-2.4.20-pre7/arch/mips/mips-boards/atlas/atlas_int.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/atlas/atlas_int.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/atlas/atlas_int.c	Thu Sep 12 20:01:40 2002
@@ -19,7 +19,7 @@
  *
  * ########################################################################
  *
- * Routines for generic manipulation of the interrupts found on the MIPS 
+ * Routines for generic manipulation of the interrupts found on the MIPS
  * Atlas board.
  *
  */
@@ -104,7 +104,7 @@
 	unsigned long int_status;
 	int irq, cpu = smp_processor_id();
 
-	int_status = atlas_hw0_icregs->intstatus; 
+	int_status = atlas_hw0_icregs->intstatus;
 
 	/* if int_status == 0, then the interrupt has already been cleared */
 	if (int_status == 0)
@@ -127,7 +127,7 @@
 	action->handler(irq, action->dev_id, regs);
 	irq_exit(cpu, irq);
 
-	return;		
+	return;
 }
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -139,11 +139,11 @@
 {
 	int i;
 
-	/* 
-	 * Mask out all interrupt by writing "1" to all bit position in 
-	 * the interrupt reset reg. 
+	/*
+	 * Mask out all interrupt by writing "1" to all bit position in
+	 * the interrupt reset reg.
 	 */
-	atlas_hw0_icregs->intrsten = 0xffffffff;    
+	atlas_hw0_icregs->intrsten = 0xffffffff;
 
 	/* Now safe to set the exception vector. */
 	set_except_vector(0, mipsIRQ);
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.4.20-pre7/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/atlas/atlas_setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/atlas/atlas_setup.c	Thu Sep 12 20:01:40 2002
@@ -59,6 +59,8 @@
 }
 
 extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+extern unsigned long mips_rtc_get_time(void);
 
 void __init atlas_setup(void)
 {
@@ -86,7 +88,7 @@
 		prom_printf("Config serial console: %s\n", serial_console);
 		console_setup(serial_console, NULL);
 	}
-#endif	  
+#endif
 
 #ifdef CONFIG_REMOTE_DEBUG
 	argptr = prom_getcmdline();
@@ -124,6 +126,8 @@
 
 	rtc_ops = &atlas_rtc_ops;
 	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+	rtc_get_time = mips_rtc_get_time;
 
 	mips_reboot_setup();
 }
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/Makefile linux-2.4.20-pre7/arch/mips/mips-boards/generic/Makefile
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/Makefile	Thu Sep 12 20:01:40 2002
@@ -5,12 +5,12 @@
 # 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.
@@ -28,7 +28,9 @@
 O_TARGET := mipsboards.o
 
 obj-y				:= mipsIRQ.o reset.o display.o init.o \
-				   memory.o printf.o cmdline.o time.o
+				   memory.o printf.o cmdline.o
+obj-$(CONFIG_MIPS_ATLAS)	+= time.o
+obj-$(CONFIG_MIPS_MALTA)	+= time.o
 obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb_hook.o
 
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/display.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/display.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/display.c	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/display.c	Thu Sep 12 20:01:40 2002
@@ -18,7 +18,7 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  * ########################################################################
- * 
+ *
  * Display routines for display messages in MIPS boards ascii display.
  *
  */
@@ -39,9 +39,11 @@
 	}
 }
 
+#ifndef CONFIG_MIPS_SEAD
 void mips_display_word(unsigned int num)
 {
         volatile unsigned int *display = (void *)ASCII_DISPLAY_WORD_BASE;
-	
+
 	*display = num;
 }
+#endif
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/gdb_hook.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/gdb_hook.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/gdb_hook.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/gdb_hook.c	Thu Sep 12 20:01:40 2002
@@ -67,28 +67,28 @@
 	serial_in(&kdb_port_info, UART_MSR);
 
 	/*
-	 * Now, initialize the UART 
+	 * 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 
+		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;	
+	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 */
@@ -102,7 +102,7 @@
 	return generic_putDebugChar(c);
 }
 
-char getDebugChar(void) 
+char getDebugChar(void)
 {
 	return generic_getDebugChar();
 }
@@ -156,7 +156,7 @@
 
 static int saa9730_kgdb_active = 0;
 
-void saa9730_kgdb_hook(void) 
+void saa9730_kgdb_hook(void)
 {
         volatile unsigned char t;
 
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/init.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/init.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/init.c	Thu Sep 12 20:01:40 2002
@@ -54,8 +54,8 @@
 {
 	/*
 	 * 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 
+	 * 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.
 	 */
 	int i, index=0;
@@ -95,7 +95,7 @@
 		ea[i] = num;
 	}
 }
- 
+
 int get_ethernet_addr(char *ethernet_addr)
 {
         char *ethaddr_str;
@@ -135,7 +135,7 @@
 	case MIPS_REVISION_CORID_CORE_LV:
 	case MIPS_REVISION_CORID_CORE_FPGA:
 		/*
-		 * Setup the North bridge to do Master byte-lane swapping 
+		 * Setup the North bridge to do Master byte-lane swapping
 		 * when running in bigendian.
 		 */
 #if defined(__MIPSEL__)
@@ -149,15 +149,15 @@
 		set_io_port_base(MALTA_GT_PORT_BASE);
 #else
 		set_io_port_base(KSEG1);
-#endif		
+#endif
 
 		break;
 	case MIPS_REVISION_CORID_BONITO64:
 	case MIPS_REVISION_CORID_CORE_20K:
-		/* 
+		/*
 		 * Disable Bonito IOBC.
 		 */
-		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & 
+		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
 			~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
 			  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
 
@@ -166,12 +166,12 @@
 		 * when running in bigendian.
 		 */
 #if defined(__MIPSEL__)
-		BONITO_BONGENCFG = BONITO_BONGENCFG & 
-			~(BONITO_BONGENCFG_MSTRBYTESWAP | 
+		BONITO_BONGENCFG = BONITO_BONGENCFG &
+			~(BONITO_BONGENCFG_MSTRBYTESWAP |
 			  BONITO_BONGENCFG_BYTESWAP);
 #else
-		BONITO_BONGENCFG = BONITO_BONGENCFG | 
-			BONITO_BONGENCFG_MSTRBYTESWAP | 
+		BONITO_BONGENCFG = BONITO_BONGENCFG |
+			BONITO_BONGENCFG_MSTRBYTESWAP |
 			BONITO_BONGENCFG_BYTESWAP;
 #endif
 
@@ -187,7 +187,7 @@
 #if defined(__MIPSEL__)
 		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
 #else
-		MSC_WRITE(MSC01_PCI_SWAP, 
+		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);
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/memory.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/memory.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/memory.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/memory.c	Thu Sep 12 20:01:40 2002
@@ -19,9 +19,9 @@
  *
  * ########################################################################
  *
- * PROM library functions for acquiring/using memory descriptors given to 
+ * PROM library functions for acquiring/using memory descriptors given to
  * us from the YAMON.
- * 
+ *
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -83,11 +83,11 @@
 	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 
+	 * 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 
+	 * This mean that this area can't be used as DMA memory for PCI
 	 * devices.
 	 */
 	mdesc[2].type = yamon_dontuse;
@@ -148,7 +148,7 @@
 		size = p->size;
 
 		add_memory_region(base, size, type);
-                p++; 
+                p++;
 	}
 }
 
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/mipsIRQ.S linux-2.4.20-pre7/arch/mips/mips-boards/generic/mipsIRQ.S
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/mipsIRQ.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/mipsIRQ.S	Thu Sep 12 20:01:40 2002
@@ -59,7 +59,7 @@
  * 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
@@ -78,7 +78,9 @@
 	CLI
 	.set	at
 
-	mfc0	s0, CP0_CAUSE		# get irq mask
+	mfc0	s0, CP0_CAUSE		# get irq bits
+	mfc0	s1, CP0_STATUS		# get irq mask
+	and	s0, s1
 
 	/* First we check for r4k counter/timer IRQ. */
 	andi	a0, s0, CAUSEF_IP7
@@ -94,14 +96,14 @@
 	 nop
 
 1:
-#if defined(CONFIG_MIPS_SEAD) 	
+#if defined(CONFIG_MIPS_SEAD)
 	beq	a0, zero, 1f
 	 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	
+ 	 andi	a0, s0, CAUSEF_IP5
 #endif
-	
+
 	/* Wheee, combined hardware level zero interrupt. */
 #if defined(CONFIG_MIPS_ATLAS)
 	jal	atlas_hw0_irqdispatch
@@ -110,7 +112,7 @@
 #elif defined(CONFIG_MIPS_SEAD)
 	jal	sead_hw0_irqdispatch
 #else
-#error "MIPS board not supported\n"	
+#error "MIPS board not supported\n"
 #endif
 	 move	a0, sp			# delay slot
 
@@ -118,24 +120,24 @@
 	 nop				# delay slot
 
 1:
-#if defined(CONFIG_MIPS_SEAD) 	
+#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	
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
 	 nop				# delay slot
-1:	
-#endif	
-
+1:
+#endif
+#if defined(CONFIG_MIPS_MALTA)
 	beq	a0, zero, 1f            # check hw3 (coreHI) interrupt
 	 nop
 	jal	corehi_irqdispatch
-	 move	a0, sp			
+	 move	a0, sp
 	j	ret_from_irq
-	 nop				
-1:	
-
+	 nop
+1:
+#endif
 	/*
 	 * 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 -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/pci.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/pci.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/pci.c	Thu Sep 12 20:01:40 2002
@@ -72,12 +72,12 @@
 
 		/* Clear cause register bits */
 		GT_READ(GT_INTRCAUSE_OFS, intr);
-		GT_WRITE(GT_INTRCAUSE_OFS, intr & 
-			 ~(GT_INTRCAUSE_MASABORT0_BIT | 
+		GT_WRITE(GT_INTRCAUSE_OFS, intr &
+			 ~(GT_INTRCAUSE_MASABORT0_BIT |
 			   GT_INTRCAUSE_TARABORT0_BIT));
 
 		/* Setup address */
-		GT_WRITE(GT_PCI0_CFGADDR_OFS, 
+		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)   |
@@ -85,9 +85,9 @@
 
 		if (access_type == PCI_ACCESS_WRITE) {
 			if (bus == 0 && dev_fn == 0) {
-				/* 
-				 * The Galileo system controller is acting 
-				 * differently than other devices. 
+				/*
+				 * The Galileo system controller is acting
+				 * differently than other devices.
 				 */
 				GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
 			} else {
@@ -95,9 +95,9 @@
 			}
 		} else {
 			if (bus == 0 && dev_fn == 0) {
-				/* 
-				 * The Galileo system controller is acting 
-				 * differently than other devices. 
+				/*
+				 * The Galileo system controller is acting
+				 * differently than other devices.
 				 */
 				GT_READ(GT_PCI0_CFGDATA_OFS, *data);
 			} else {
@@ -108,15 +108,15 @@
 		/* Check for master or target abort */
 		GT_READ(GT_INTRCAUSE_OFS, intr);
 
-		if (intr & (GT_INTRCAUSE_MASABORT0_BIT | 
+		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_WRITE(GT_INTRCAUSE_OFS, intr &
+				 ~(GT_INTRCAUSE_MASABORT0_BIT |
 				   GT_INTRCAUSE_TARABORT0_BIT));
 
 			return -1;
@@ -133,12 +133,12 @@
 		}
 
 		/* Clear cause register bits */
-		BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | 
+		BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
 				  BONITO_PCICMD_MTABORT_CLR);
 
-		/* 
-		 * Setup pattern to be used as PCI "address" for 
-		 * Type 0 cycle 
+		/*
+		 * Setup pattern to be used as PCI "address" for
+		 * Type 0 cycle
 		 */
 		if (bus == 0) {
 		        /* IDSEL */
@@ -153,10 +153,10 @@
 
 		/* 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;
@@ -164,7 +164,7 @@
 		        /* Type 1 */
 		        BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
 		}
-	  
+
 		/* Flush Bonito register block */
 		dummy = BONITO_PCIMAP_CFG;
 		__asm__ __volatile__(
@@ -176,28 +176,28 @@
 
 		/* Perform access */
 		if (access_type == PCI_ACCESS_WRITE) {
-		        *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + 
+		        *(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 + 
+		        *(u32 *)data =
+			  *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE +
 					    (pci_addr & 0xffff)));
 		}
 
 		/* Detect Master/Target abort */
-		if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | 
+		if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
 				     BONITO_PCICMD_MTABORT_CLR) )
 		{
 		        /* Error occurred */
 
 		        /* Clear bits */
-		        BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | 
+		        BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
 					  BONITO_PCICMD_MTABORT_CLR);
-    
+
 			return -1;
 		}
 	        break;
@@ -210,8 +210,8 @@
 		}
 
 		/* Clear status register bits. */
-		MSC_WRITE(MSC01_PCI_INTSTAT, 
-			  (MSC01_PCI_INTCFG_MA_BIT | 
+		MSC_WRITE(MSC01_PCI_INTSTAT,
+			  (MSC01_PCI_INTCFG_MA_BIT |
 			   MSC01_PCI_INTCFG_TA_BIT));
 
 		/* Setup address */
@@ -236,7 +236,7 @@
 
 		/* Detect Master/Target abort */
 		MSC_READ(MSC01_PCI_INTSTAT, intr);
-		if (intr & (MSC01_PCI_INTCFG_MA_BIT | 
+		if (intr & (MSC01_PCI_INTCFG_MA_BIT |
 			    MSC01_PCI_INTCFG_TA_BIT))
 		{
 		        /* Error occurred */
@@ -244,7 +244,7 @@
 		        /* Clear bits */
 			MSC_READ(MSC01_PCI_INTSTAT, intr);
 			MSC_WRITE(MSC01_PCI_INTSTAT,
-				  (MSC01_PCI_INTCFG_MA_BIT | 
+				  (MSC01_PCI_INTCFG_MA_BIT |
 				   MSC01_PCI_INTCFG_TA_BIT));
 
 			return -1;
@@ -300,7 +300,7 @@
 
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
-	
+
 	if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data))
 		return -1;
 
@@ -314,7 +314,7 @@
 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;
 
@@ -334,11 +334,11 @@
 
 	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))) | 
+	data = (data & ~(0xffff << ((where & 3) << 3))) |
 	       (val << ((where & 3) << 3));
 
 	if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data))
@@ -369,6 +369,55 @@
 	mips_pcibios_write_config_dword
 };
 
+int mips_pcibios_iack(void)
+{
+	int irq;
+        u32 dummy;
+
+	/*
+	 * Determine highest priority pending interrupt by performing
+	 * a PCI Interrupt Acknowledge cycle.
+	 */
+	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:
+		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;
+		break;
+	case MIPS_REVISION_CORID_BONITO64:
+	case MIPS_REVISION_CORID_CORE_20K:
+		/* The following will generate a PCI IACK cycle on the
+		 * Bonito controller. It's a little bit kludgy, but it
+		 * was the easiest way to implement it in hardware at
+		 * the given time.
+		 */
+		BONITO_PCIMAP_CFG = 0x20000;
+
+		/* 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");
+
+		irq = *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE));
+		irq &= 0xff;
+		BONITO_PCIMAP_CFG = 0;
+		break;
+	default:
+	        printk("Unknown Core card, don't know the system controller.\n");
+		return -1;
+	}
+	return irq;
+}
+
 void __init pcibios_init(void)
 {
 #ifdef CONFIG_MIPS_MALTA
@@ -383,11 +432,11 @@
 	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 
+		/*
+		 * 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 
+		 * 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,
@@ -398,7 +447,7 @@
 			 GT_PCI0_CFGADDR_CONFIGEN_BIT );
 
 		/* Perform the write */
-		GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); 
+		GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE));
 		break;
 	}
 
@@ -428,15 +477,15 @@
 		}
 	}
 
-	/* 
-	 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 
+	/*
+	 * 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); 
-       
+	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);
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/printf.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/printf.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/printf.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/printf.c	Thu Sep 12 20:01:40 2002
@@ -32,20 +32,20 @@
 #include <asm/serial.h>
 
 
-#ifdef CONFIG_MIPS_ATLAS 
-/* 
- * Atlas registers are memory mapped on 64-bit aligned boundaries and 
+#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD)
+/*
+ * 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 inl(info->port + offset*8) & 0xff;
+	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)
 {
-	outl(value, info->port + offset*8);
+	*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value;
 }
 
 #define serial_in  atlas_serial_in
@@ -70,8 +70,8 @@
 };
 
 /*
- * Hooks to fake "prom" console I/O before devices 
- * are fully initialized. 
+ * Hooks to fake "prom" console I/O before devices
+ * are fully initialized.
  */
 static struct async_struct prom_port_info = {0};
 
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/generic/time.c linux-2.4.20-pre7/arch/mips/mips-boards/generic/time.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/generic/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/generic/time.c	Thu Sep 12 20:01:40 2002
@@ -35,6 +35,7 @@
 #include <asm/hardirq.h>
 #include <asm/div64.h>
 #include <asm/cpu.h>
+#include <asm/time.h>
 
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
@@ -46,8 +47,6 @@
 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)
 
 #if defined(CONFIG_MIPS_ATLAS)
@@ -57,7 +56,7 @@
 static char display_string[] = "        LINUX ON MALTA       ";
 #endif
 static unsigned int display_count = 0;
-#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) 
+#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
 
 #define MIPS_CPU_TIMER_IRQ 7
 
@@ -71,13 +70,6 @@
 
 void mips_timer_interrupt(struct pt_regs *regs)
 {
-	int cpu = smp_processor_id();
-	int irq = MIPS_CPU_TIMER_IRQ;
-
-	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)
@@ -85,15 +77,12 @@
 
 	}
 
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
+	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
 }
 
-/* 
+/*
  * Figure out the r4k offset, the amount to increment the compare
- * register for each time tick. 
+ * register for each time tick.
  * Use the RTC to calculate offset.
  */
 static unsigned int __init cal_r4koff(void)
@@ -141,7 +130,7 @@
 		if ((hour & 0xf) == 0xc)
 		        hour &= 0x80;
 	        if (hour & 0x80)
-		        hour = (hour & 0xf) + 12;     
+		        hour = (hour & 0xf) + 12;
 	}
 	day = CMOS_READ(RTC_DAY_OF_MONTH);
 	mon = CMOS_READ(RTC_MONTH);
@@ -162,14 +151,14 @@
 
 	__save_and_cli(flags);
 
-        /* Set Data mode - binary. */ 
+        /* Set Data mode - binary. */
         CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
 
 	printk("calculating r4koff... ");
 	r4k_offset = cal_r4koff();
 	printk("%08x(%d)\n", r4k_offset, r4k_offset);
 
-        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == 
+        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) ==
 	    (PRID_COMP_MIPS | PRID_IMP_20KC))
 		est_freq = r4k_offset*HZ;
 	else
@@ -177,7 +166,7 @@
 
 	est_freq += 5000;    /* round */
 	est_freq -= est_freq%10000;
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
 	       (est_freq%1000000)*100/1000000);
 
 	__restore_flags(flags);
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/malta/Makefile linux-2.4.20-pre7/arch/mips/mips-boards/malta/Makefile
--- linux-2.4.20-pre6/arch/mips/mips-boards/malta/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/malta/Makefile	Thu Sep 12 20:01:40 2002
@@ -7,12 +7,12 @@
 # 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.
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/malta/malta_int.c linux-2.4.20-pre7/arch/mips/mips-boards/malta/malta_int.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/malta/malta_int.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/malta/malta_int.c	Thu Sep 12 20:01:40 2002
@@ -16,9 +16,9 @@
  *  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 
+ * 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 
+ * The interrupt controller is located in the South Bridge a PIIX4 device
  * with two internal 82C95 interrupt controllers.
  */
 #include <linux/config.h>
@@ -41,207 +41,49 @@
 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);
+extern int mips_pcibios_iack(void);
 
 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;
+	unsigned long flags;
 
-	case MIPS_REVISION_CORID_BONITO64:
-	case MIPS_REVISION_CORID_CORE_20K:
-	        /*
-		 * Determine highest priority pending interrupt by reading 
-		 * the IRR register of controller 1.
-		 */
+	spin_lock_irqsave(&mips_irq_lock, flags);
 
-		outb(PIIX4_OCW3_SEL | PIIX4_OCW3_IRR, PIIX4_ICTLR1_OCW3);
-		irr = inb(PIIX4_ICTLR1_OCW3) & ~(cached_int_mask & 0xff);
+	*irq = mips_pcibios_iack();
 
-		if (!irr) {
-		        printk("We got a spurious interrupt from PIIX4.\n");
+	/*
+	 * 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))) {
+			spin_unlock_irqrestore(&mips_irq_lock, flags);
+			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;
+			return -1;    /* Spurious interrupt. */
 		}
-
-		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;
 	}
 
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+
 	return 0;
 }
 
 void malta_hw0_irqdispatch(struct pt_regs *regs)
 {
 	int irq;
-	struct irqaction *action;
 
 	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);
 }
 
@@ -288,38 +130,9 @@
 
 void __init init_IRQ(void)
 {
-	unsigned int i;
-
 	set_except_vector(0, mipsIRQ);
 	init_generic_irq();
-	
-	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;
-	}
+	init_i8259_irqs();
 
 #ifdef CONFIG_REMOTE_DEBUG
 	if (remote_debug) {
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/malta/malta_setup.c linux-2.4.20-pre7/arch/mips/mips-boards/malta/malta_setup.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/malta/malta_setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mips-boards/malta/malta_setup.c	Thu Sep 12 20:01:40 2002
@@ -104,7 +104,7 @@
 	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);
@@ -145,14 +145,6 @@
 	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
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/sead/Makefile linux-2.4.20-pre7/arch/mips/mips-boards/sead/Makefile
--- linux-2.4.20-pre6/arch/mips/mips-boards/sead/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/mips-boards/sead/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,40 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2002 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 SEAD 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
+
+all: sead.o
+
+O_TARGET := sead.o
+
+obj-y	:= sead_int.o sead_setup.o sead_time.o
+
+include $(TOPDIR)/Rules.make
+
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/sead/sead_int.c linux-2.4.20-pre7/arch/mips/mips-boards/sead/sead_int.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/sead/sead_int.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/mips-boards/sead/sead_int.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,116 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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
+ * Sead 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/sead.h>
+#include <asm/mips-boards/seadint.h>
+
+extern asmlinkage void mipsIRQ(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+void disable_sead_irq(unsigned int irq_nr)
+{
+	if (irq_nr == SEADINT_UART0)
+		clear_cp0_status(0x00000400);
+	else
+		if (irq_nr == SEADINT_UART1)
+			clear_cp0_status(0x00000800);
+}
+
+void enable_sead_irq(unsigned int irq_nr)
+{
+	if (irq_nr == SEADINT_UART0)
+		set_cp0_status(0x00000400);
+	else
+		if (irq_nr == SEADINT_UART1)
+			set_cp0_status(0x00000800);
+}
+
+static unsigned int startup_sead_irq(unsigned int irq)
+{
+	enable_sead_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sead_irq	disable_sead_irq
+
+#define mask_and_ack_sead_irq disable_sead_irq
+
+static void end_sead_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_sead_irq(irq);
+}
+
+static struct hw_interrupt_type sead_irq_type = {
+	"SEAD",
+	startup_sead_irq,
+	shutdown_sead_irq,
+	enable_sead_irq,
+	disable_sead_irq,
+	mask_and_ack_sead_irq,
+	end_sead_irq,
+	NULL
+};
+
+void sead_hw0_irqdispatch(struct pt_regs *regs)
+{
+	do_IRQ(0, regs);
+}
+
+void sead_hw1_irqdispatch(struct pt_regs *regs)
+{
+	do_IRQ(1, regs);
+}
+
+void __init init_IRQ(void)
+{
+	int i;
+
+        /*
+         * Mask out all interrupt
+	 */
+	clear_cp0_status(0x0000ff00);
+
+	/* Now safe to set the exception vector. */
+	set_except_vector(0, mipsIRQ);
+
+	init_generic_irq();
+
+	for (i = 0; i <= SEADINT_END; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= NULL;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].lock	= SPIN_LOCK_UNLOCKED;
+		irq_desc[i].handler	= &sead_irq_type;
+	}
+}
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/sead/sead_setup.c linux-2.4.20-pre7/arch/mips/mips-boards/sead/sead_setup.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/sead/sead_setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/mips-boards/sead/sead_setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,81 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * SEAD specific setup.
+ */
+#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/seadint.h>
+#include <asm/time.h>
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+char serial_console[20];
+#endif
+
+extern void mips_reboot_setup(void);
+extern void mips_time_init(void);
+extern void mips_timer_setup(struct irqaction *irq);
+
+const char *get_system_type(void)
+{
+	return "MIPS SEAD";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init sead_setup(void)
+{
+	char *argptr;
+
+	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
+
+	argptr = prom_getcmdline();
+
+	if ((argptr = strstr(argptr, "nofpu")) != NULL)
+		mips_cpu.options &= ~MIPS_CPU_FPU;
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+
+	mips_reboot_setup();
+}
diff -urN linux-2.4.20-pre6/arch/mips/mips-boards/sead/sead_time.c linux-2.4.20-pre7/arch/mips/mips-boards/sead/sead_time.c
--- linux-2.4.20-pre6/arch/mips/mips-boards/sead/sead_time.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/mips-boards/sead/sead_time.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,149 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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 <asm/hardirq.h>
+#include <asm/cpu.h>
+
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+extern volatile unsigned long wall_jiffies;
+
+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_IRQ5)
+
+static char display_string[] = "        LINUX ON SEAD       ";
+
+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)
+{
+	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
+ * is provably more robust.
+ */
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int irq = MIPS_CPU_TIMER_IRQ;
+
+	irq_enter(cpu, irq);
+
+	do {
+		kstat.irqs[cpu][irq]++;
+		do_timer(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);
+
+	irq_exit(cpu, irq);
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+/*
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+	/*
+	 * The SEAD board doesn't have a real time clock, so we can't
+	 * really calculate the timer offset.
+	 * For now we hardwire the SEAD board frequency to 12MHz.
+	 */
+	return(6000000/HZ);
+}
+
+void __init mips_time_init(void)
+{
+        unsigned int est_freq, flags;
+
+	__save_and_cli(flags);
+
+        /* Start r4k counter. */
+        write_32bit_cp0_register(CP0_COUNT, 0);
+
+	printk("calculating r4koff... ");
+	r4k_offset = cal_r4koff();
+	printk("%08lx(%d)\n", r4k_offset, (int) 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 += 5000;    /* round */
+	est_freq -= est_freq%10000;
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+	       (est_freq%1000000)*100/1000000);
+
+	__restore_flags(flags);
+}
+
+void __init mips_timer_setup(struct irqaction *irq)
+{
+	/* 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);
+
+        /* 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 -urN linux-2.4.20-pre6/arch/mips/mm/Makefile linux-2.4.20-pre7/arch/mips/mm/Makefile
--- linux-2.4.20-pre6/arch/mips/mm/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/Makefile	Thu Sep 12 20:01:40 2002
@@ -20,8 +20,10 @@
 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_R5000)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \
+				   r5k-sc.o
+obj-$(CONFIG_CPU_NEVADA)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \
+				   r5k-sc.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
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-andes.c linux-2.4.20-pre7/arch/mips/mm/c-andes.c
--- linux-2.4.20-pre6/arch/mips/mm/c-andes.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-andes.c	Thu Sep 12 20:01:40 2002
@@ -124,6 +124,6 @@
 			printk("Unknown L2 line size\n");
 			while(1);
 	}
-    
+
         flush_cache_l1();
 }
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-mips32.c linux-2.4.20-pre7/arch/mips/mm/c-mips32.c
--- linux-2.4.20-pre6/arch/mips/mm/c-mips32.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-mips32.c	Thu Sep 12 20:01:40 2002
@@ -424,33 +424,33 @@
 	unsigned int lsize;
 
         if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
+	        /*
+		 * 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 = 
+		mips_cpu.icache.sets =
 			(icache_size / ic_lsize) / mips_cpu.icache.ways;
 	} else {
-	       config1 = read_mips32_cp0_config1(); 
+	       config1 = read_mips32_cp0_config1();
 
 	       if ((lsize = ((config1 >> 19) & 7)))
 		       mips_cpu.icache.linesz = 2 << lsize;
-	       else 
+	       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 * 
+	       icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways *
 		             ic_lsize;
 	}
 	printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n",
@@ -463,32 +463,32 @@
 	unsigned int lsize;
 
         if (!(config & (1 << 31))) {
-	        /* 
-		 * Not a MIPS32 complainant CPU. 
+	        /*
+		 * 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 = 
+		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 
+		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 = 
+		dcache_size =
 			mips_cpu.dcache.sets * mips_cpu.dcache.ways
 			* dc_lsize;
 	}
@@ -638,12 +638,12 @@
 
 	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 = 
+		mips_cpu.scache.sets =
 		  (scache_size / sc_lsize) / mips_cpu.scache.ways;
 
 		setup_scache_funcs();
@@ -657,11 +657,7 @@
 {
 	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
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-r3k.c linux-2.4.20-pre7/arch/mips/mm/c-r3k.c
--- linux-2.4.20-pre6/arch/mips/mm/c-r3k.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-r3k.c	Thu Sep 12 20:01:40 2002
@@ -19,7 +19,6 @@
 #include <asm/system.h>
 #include <asm/isadep.h>
 #include <asm/io.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
@@ -50,8 +49,8 @@
 		for (size = 128; size <= 0x40000; size <<= 1)
 			*(p + size) = 0;
 		*p = -1;
-		for (size = 128; 
-		     (size <= 0x40000) && (*(p + size) == 0); 
+		for (size = 128;
+		     (size <= 0x40000) && (*(p + size) == 0);
 		     size <<= 1)
 			;
 		if (size > 0x40000)
@@ -97,7 +96,7 @@
 	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)
@@ -239,7 +238,7 @@
 static inline void r3k_flush_cache_all(void)
 {
 }
- 
+
 static inline void r3k___flush_cache_all(void)
 {
 	r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
@@ -314,7 +313,7 @@
 
 static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
-	wbflush();
+	iob();
 	r3k_flush_dcache_range(start, start + size);
 }
 
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-r4k.c linux-2.4.20-pre7/arch/mips/mm/c-r4k.c
--- linux-2.4.20-pre6/arch/mips/mm/c-r4k.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-r4k.c	Thu Sep 12 20:01:40 2002
@@ -1150,12 +1150,6 @@
 	}
 }
 
-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
@@ -1200,6 +1194,12 @@
 {
         switch (mips_cpu.cputype) {
         case CPU_VR41XX:
+        case CPU_VR4111:
+        case CPU_VR4121:
+        case CPU_VR4122:
+        case CPU_VR4131:
+        case CPU_VR4181:
+        case CPU_VR4181A:
                 icache_size = 1 << (10 + ((config >> 9) & 7));
                 break;
         default:
@@ -1216,6 +1216,12 @@
 {
         switch (mips_cpu.cputype) {
         case CPU_VR41XX:
+        case CPU_VR4111:
+        case CPU_VR4121:
+        case CPU_VR4122:
+        case CPU_VR4131:
+        case CPU_VR4181:
+        case CPU_VR4181A:
                 dcache_size = 1 << (10 + ((config >> 6) & 7));
                 break;
         default:
@@ -1358,7 +1364,7 @@
 	_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_wback = r4k_dma_cache_wback_inv_pc;
 	_dma_cache_inv = r4k_dma_cache_inv_pc;
 }
 
@@ -1441,7 +1447,7 @@
 	___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_wback = r4k_dma_cache_wback_inv_sc;
 	_dma_cache_inv = r4k_dma_cache_inv_sc;
 }
 
@@ -1456,23 +1462,31 @@
 	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
 	sc_present = probe_scache_kseg1(config);
 
-	if (sc_present) {
-		setup_scache_funcs();
+	if (!sc_present) {
+		setup_noscache_funcs();
 		return;
 	}
 
-	setup_noscache_funcs();
+	switch(mips_cpu.cputype) {
+	case CPU_R5000:
+	case CPU_NEVADA:
+			setup_noscache_funcs();
+#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+			r5k_sc_init();
+#endif
+			break;
+	default:
+			setup_scache_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
+	change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-r5432.c linux-2.4.20-pre7/arch/mips/mm/c-r5432.c
--- linux-2.4.20-pre6/arch/mips/mm/c-r5432.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-r5432.c	Thu Sep 12 20:01:40 2002
@@ -352,7 +352,7 @@
 	blast_dcache32_page((unsigned long)page_address(page));
 }
 
-static void 
+static void
 r5432_flush_icache_range(unsigned long start, unsigned long end)
 {
 	r5432_flush_cache_all_d32i32();
@@ -455,7 +455,7 @@
 {
 	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
 
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-rm7k.c linux-2.4.20-pre7/arch/mips/mm/c-rm7k.c
--- linux-2.4.20-pre6/arch/mips/mm/c-rm7k.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-rm7k.c	Thu Sep 12 20:01:40 2002
@@ -139,7 +139,7 @@
 		a += sc_lsize;
 	}
 
-	if (!rm7k_tcache_enabled) 
+	if (!rm7k_tcache_enabled)
 		return;
 
 	a = addr & ~(tc_pagesize - 1);
@@ -150,7 +150,7 @@
 		a += tc_pagesize;
 	}
 }
-	       
+
 static void
 rm7k_dma_cache_inv(unsigned long addr, unsigned long size)
 {
@@ -165,7 +165,7 @@
 		a += sc_lsize;
 	}
 
-	if (!rm7k_tcache_enabled) 
+	if (!rm7k_tcache_enabled)
 		return;
 
 	a = addr & ~(tc_pagesize - 1);
@@ -210,10 +210,10 @@
 }
 
 
-/* 
+/*
  * This function is executed in the uncached segment KSEG1.
  * It must not touch the stack, because the stack pointer still points
- * into KSEG0. 
+ * into KSEG0.
  *
  * Three options:
  *	- Write it in assembly and guarantee that we don't use the stack.
@@ -228,12 +228,12 @@
 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"
@@ -265,7 +265,7 @@
 	func();
 	printk("Done\n");
 }
- 
+
 static inline void probe_tcache(unsigned long config)
 {
 	if ((config >> 17) & 1)
@@ -275,10 +275,10 @@
 	 * 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 
+	 * 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. 
+	 * to probe it.
 	 */
 	printk(KERN_INFO "Tertiary cache present, %s enabled\n",
 	       config&(1<<12) ? "already" : "not (yet)");
@@ -319,9 +319,7 @@
 			: "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
 	}
 
-#ifndef CONFIG_MIPS_UNCACHED
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT);
-#endif
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-sb1.c linux-2.4.20-pre7/arch/mips/mm/c-sb1.c
--- linux-2.4.20-pre6/arch/mips/mm/c-sb1.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-sb1.c	Thu Sep 12 20:01:40 2002
@@ -12,11 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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>
@@ -63,7 +63,7 @@
  * 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
@@ -80,7 +80,7 @@
 	 * 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
 	 */
@@ -104,7 +104,7 @@
 		".set noreorder             \n"
 		".set mips2                 \n"
 		"sync                       \n"
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */			
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
 		"sync                       \n"
 #endif
 		".set pop                   \n");
@@ -160,7 +160,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \n" 
+		"     move   $1, %0         \n"
 		"1:                         \n"
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 		".align 3                   \n"
@@ -199,7 +199,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \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 */
@@ -279,9 +279,9 @@
 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, 
+	/* 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 
+	   lw and the cache op
 	*/
 	unsigned long flags;
 	local_irq_save(flags);
@@ -371,7 +371,7 @@
 	 * 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
 	 */
@@ -403,23 +403,23 @@
 
 /*
  * 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 
+ * 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 
- *   
+ * 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 
+ * 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 
+ * 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");	
+		:::"memory");
 }
 
 /*
@@ -433,13 +433,13 @@
  * 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));
 }
 
@@ -462,7 +462,7 @@
 	} else if (config_field == 7) {
 		/* JDCXXX - Find a graceful way to abort. */
 		return 0;
-	} 
+	}
 	return (1<<(config_field + 1));
 }
 
@@ -519,6 +519,6 @@
 	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
 	_flush_icache_all = sb1_flush_icache_all;
 
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 	flush_cache_all();
 }
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-tx39.c linux-2.4.20-pre7/arch/mips/mm/c-tx39.c
--- linux-2.4.20-pre6/arch/mips/mm/c-tx39.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-tx39.c	Thu Sep 12 20:01:40 2002
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/isadep.h>
 #include <asm/io.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
@@ -63,8 +62,8 @@
 static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 {
 	unsigned long end, a;
-	wbflush();
 
+	iob();
 	a = addr & ~(dcache_lsize - 1);
 	end = (addr + size) & ~(dcache_lsize - 1);
 	while (1) {
@@ -89,7 +88,7 @@
 	write_32bit_cp0_register(CP0_CONF, config);
 	__restore_flags(flags);
 }
- 
+
 static void tx39_flush_cache_mm(struct mm_struct *mm)
 {
 	if(mm->context != 0) {
diff -urN linux-2.4.20-pre6/arch/mips/mm/c-tx49.c linux-2.4.20-pre7/arch/mips/mm/c-tx49.c
--- linux-2.4.20-pre6/arch/mips/mm/c-tx49.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/c-tx49.c	Thu Sep 12 20:01:40 2002
@@ -387,11 +387,7 @@
 	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
+		change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -urN linux-2.4.20-pre6/arch/mips/mm/extable.c linux-2.4.20-pre7/arch/mips/mm/extable.c
--- linux-2.4.20-pre6/arch/mips/mm/extable.c	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/arch/mips/mm/extable.c	Thu Sep 12 20:01:40 2002
@@ -36,14 +36,13 @@
 search_exception_table(unsigned long addr)
 {
 	unsigned long ret = 0;
-	
+
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 	return ret;
 #else
 	unsigned long flags;
-
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
 
diff -urN linux-2.4.20-pre6/arch/mips/mm/init.c linux-2.4.20-pre7/arch/mips/mm/init.c
--- linux-2.4.20-pre6/arch/mips/mm/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/init.c	Thu Sep 12 20:01:40 2002
@@ -67,9 +67,9 @@
 {
 	unsigned long order, size;
 	struct page *page;
-	if(mips_cpu.options & MIPS_CPU_VCE) 
+	if(mips_cpu.options & MIPS_CPU_VCE)
 		order = 3;
-	else 
+	else
 		order = 0;
 
 	empty_zero_page = __get_free_pages(GFP_KERNEL, order);
@@ -367,7 +367,7 @@
 	unsigned long addr;
 
 	prom_free_prom_memory ();
-    
+
 	addr = (unsigned long) &__init_begin;
 	while (addr < (unsigned long) &__init_end) {
 		ClearPageReserved(virt_to_page(addr));
diff -urN linux-2.4.20-pre6/arch/mips/mm/ioremap.c linux-2.4.20-pre7/arch/mips/mm/ioremap.c
--- linux-2.4.20-pre6/arch/mips/mm/ioremap.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/ioremap.c	Thu Sep 12 20:01:40 2002
@@ -122,10 +122,11 @@
 		return NULL;
 
 	/*
-	 * Map objects in the low 512mb of address space using KSEG1, otherwise
-	 * map using page tables.
+	 * Map uncached objects in the low 512mb of address space using KSEG1,
+	 * otherwise map using page tables.
 	 */
-	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr))
+	if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
+	    flags == _CACHE_UNCACHED)
 		return (void *) KSEG1ADDR(phys_addr);
 
 	/*
@@ -137,7 +138,7 @@
 
 		t_addr = __va(phys_addr);
 		t_end = t_addr + (size - 1);
-	   
+
 		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
 			if(!PageReserved(page))
 				return NULL;
diff -urN linux-2.4.20-pre6/arch/mips/mm/loadmmu.c linux-2.4.20-pre7/arch/mips/mm/loadmmu.c
--- linux-2.4.20-pre6/arch/mips/mm/loadmmu.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/loadmmu.c	Thu Sep 12 20:01:40 2002
@@ -119,6 +119,7 @@
 #endif
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
+	case CPU_R12000:
 		ld_mmu_andes();
 		r4k_tlb_init();
 		break;
diff -urN linux-2.4.20-pre6/arch/mips/mm/pg-r4k.S linux-2.4.20-pre7/arch/mips/mm/pg-r4k.S
--- linux-2.4.20-pre6/arch/mips/mm/pg-r4k.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/pg-r4k.S	Thu Sep 12 20:01:40 2002
@@ -83,10 +83,10 @@
  *      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 
+ *      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 
+ *      four instructions that are not any kind of load or store
  *      instruction.
  *
  *      This is not allowed:    lw
diff -urN linux-2.4.20-pre6/arch/mips/mm/pg-sb1.c linux-2.4.20-pre7/arch/mips/mm/pg-sb1.c
--- linux-2.4.20-pre6/arch/mips/mm/pg-sb1.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/pg-sb1.c	Thu Sep 12 20:01:40 2002
@@ -2,7 +2,7 @@
  * 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)
  *
  *
@@ -15,11 +15,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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>
 
@@ -39,7 +39,7 @@
 	   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 
+	   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"
@@ -47,15 +47,19 @@
 		".set noat                  \n"
 		".set mips4                 \n"
 		"     addiu     $1, %0, %2  \n"  /* Calculate the end of the page to clear */
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     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"  
+		"     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"
+#endif
 		"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"
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",128(%0)  \n"  /* Prefetch 4 lines ahead     */
+#endif
 		"     bne       $1, %0, 1b  \n"
 		"     addiu     %0, %0, 32  \n"  /* Next cacheline (This instruction better be short piped!) */
 		".set pop                   \n"
@@ -71,7 +75,7 @@
 
 	/* 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 
+	 * 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
@@ -87,12 +91,14 @@
 		".set noat                  \n"
 		".set mips4                 \n"
 		"     addiu     $1, %0, %4  \n"  /* Calculate the end of the page to copy */
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     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_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_STORE_STREAMED_HINT ",  32(%1) \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0) \n"
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"  
+		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \n"
+#endif
 		"1:   lw        $2,  0(%0)  \n"  /* Block copy a cacheline */
 		"     lw        $3,  4(%0)  \n"
 		"     lw        $4,  8(%0)  \n"
@@ -101,22 +107,24 @@
 		"     lw        $7, 20(%0)  \n"
 		"     lw        $8, 24(%0)  \n"
 		"     lw        $9, 28(%0)  \n"
+#ifdef CONFIG_CPU_HAS_PREFETCH
 		"     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"  
+#endif
+		"     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"		
+		"     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" 
+		".set pop                   \n"
 		:"=r" (to),
 		"=r" (from)
 		:
diff -urN linux-2.4.20-pre6/arch/mips/mm/r5k-sc.c linux-2.4.20-pre7/arch/mips/mm/r5k-sc.c
--- linux-2.4.20-pre6/arch/mips/mm/r5k-sc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/mm/r5k-sc.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,115 @@
+/*
+ * 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/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheops.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#define SC_LINE 32
+#define SC_PAGE (128*SC_LINE)
+
+#define cache_op(base,op)                   \
+__asm__ __volatile__("				\
+		.set noreorder;                 \
+		.set mips3;                     \
+		cache %1, (%0);                 \
+		.set mips0;                     \
+		.set reorder"                   \
+		:                               \
+		: "r" (base),                   \
+		  "i" (op));
+
+static inline void blast_r5000_scache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache_op(start, R5K_Page_Invalidate_S);
+		start += SC_PAGE;
+	}
+}
+
+static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_r5000_scache();
+		return;
+	}
+
+	/* On the R5000 secondary cache we cannot
+	 * invalidate less than a page at a time.
+	 * The secondary cache is physically indexed, write-through.
+	 */
+	a = addr & ~(SC_PAGE - 1);
+	end = (addr + size - 1) & ~(SC_PAGE - 1);
+	while (a <= end) {
+		cache_op(a, R5K_Page_Invalidate_S);
+		a += SC_PAGE;
+	}
+}
+
+static void r5k_sc_enable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	change_cp0_config(CONF_SE, CONF_SE);
+	blast_r5000_scache();
+	__restore_flags(flags);
+}
+
+static void r5k_sc_disable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_r5000_scache();
+	change_cp0_config(CONF_SE, 0);
+	__restore_flags(flags);
+}
+
+static inline int __init r5k_sc_probe(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	if(config & CONF_SC)
+		return(0);
+
+	scache_size = (512*1024) << ((config >> 20)&3);
+
+	printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+			scache_size >> 10);
+
+	return 1;
+}
+
+struct bcache_ops r5k_sc_ops = {
+	r5k_sc_enable,
+	r5k_sc_disable,
+	r5k_dma_cache_inv_sc,
+	r5k_dma_cache_inv_sc
+};
+
+void __init r5k_sc_init(void)
+{
+	if (r5k_sc_probe()) {
+		r5k_sc_enable();
+		bcops = &r5k_sc_ops;
+	}
+}
diff -urN linux-2.4.20-pre6/arch/mips/mm/tlb-r3k.c linux-2.4.20-pre7/arch/mips/mm/tlb-r3k.c
--- linux-2.4.20-pre6/arch/mips/mm/tlb-r3k.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/tlb-r3k.c	Thu Sep 12 20:01:40 2002
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/isadep.h>
 #include <asm/io.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
@@ -200,12 +199,12 @@
 	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",
@@ -226,7 +225,7 @@
 		set_entryhi(entryhi);
 		set_entrylo0(entrylo0);
 		tlb_write_indexed();
-    
+
 		set_entryhi(old_ctx);
 		set_pagemask (old_pagemask);
 		local_flush_tlb_all();
@@ -244,7 +243,7 @@
 		wired++;
 		tlb_write_indexed();
 		set_entryhi(old_ctx);
-	        local_flush_tlb_all();    
+	        local_flush_tlb_all();
 		__restore_flags(flags);
 	}
 }
diff -urN linux-2.4.20-pre6/arch/mips/mm/tlb-r4k.c linux-2.4.20-pre7/arch/mips/mm/tlb-r4k.c
--- linux-2.4.20-pre6/arch/mips/mm/tlb-r4k.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/tlb-r4k.c	Thu Sep 12 20:01:40 2002
@@ -119,12 +119,11 @@
 				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);
+				set_entryhi(KSEG0 + idx*0x2000);
+				BARRIER;
 				tlb_write_indexed();
 				BARRIER;
 			}
@@ -271,19 +270,19 @@
 	wired = get_wired();
 	set_wired(wired + 1);
 	set_index(wired);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(pagemask);
 	set_entryhi(entryhi);
 	set_entrylo0(entrylo0);
 	set_entrylo1(entrylo1);
-	BARRIER;    
+	BARRIER;
 	tlb_write_indexed();
-	BARRIER;    
-    
+	BARRIER;
+
 	set_entryhi(old_ctx);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(old_pagemask);
-	local_flush_tlb_all();    
+	local_flush_tlb_all();
 	__restore_flags(flags);
 }
 
@@ -316,17 +315,17 @@
 	}
 
 	set_index(temp_tlb_entry);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(pagemask);
 	set_entryhi(entryhi);
 	set_entrylo0(entrylo0);
 	set_entrylo1(entrylo1);
-	BARRIER;    
+	BARRIER;
 	tlb_write_indexed();
-	BARRIER;    
-    
+	BARRIER;
+
 	set_entryhi(old_ctx);
-	BARRIER;    
+	BARRIER;
 	set_pagemask(old_pagemask);
 out:
 	__restore_flags(flags);
@@ -339,11 +338,11 @@
 
 	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();
diff -urN linux-2.4.20-pre6/arch/mips/mm/tlb-sb1.c linux-2.4.20-pre7/arch/mips/mm/tlb-sb1.c
--- linux-2.4.20-pre6/arch/mips/mm/tlb-sb1.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/tlb-sb1.c	Thu Sep 12 20:01:40 2002
@@ -12,11 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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>
@@ -38,13 +38,13 @@
 		"     tlbr             \n"
 		"     dmfc0  $1, $10   \n"
 		"     dsrl32 %0, $1, 0 \n"
-		"     sra    %1, $1, 0 \n"
+		"     sll    %1, $1, 0 \n"
 		"     dmfc0  $1, $2    \n"
 		"     dsrl32 %2, $1, 0 \n"
-		"     sra    %3, $1, 0 \n"
+		"     sll    %3, $1, 0 \n"
 		"     dmfc0  $1, $3    \n"
 		"     dsrl32 %4, $1, 0 \n"
-		"     sra    %5, $1, 0 \n"
+		"     sll    %5, $1, 0 \n"
 		"     mfc0   %6, $5    \n"
 		".set pop              \n"
 		: "=r" (entryhihi),
@@ -63,7 +63,11 @@
 
 void sb1_dump_tlb(void)
 {
+	unsigned long old_ctx;
+	unsigned long flags;
 	int entry;
+	__save_and_cli(flags);
+	old_ctx = get_entryhi();
 	printk("Current TLB registers state:\n"
 	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
 	       "--------------------------------------------------------------------\n");
@@ -83,6 +87,8 @@
 		dump_cur_tlb_regs();
 	}
 	printk("\n");
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
 }
 
 void local_flush_tlb_all(void)
@@ -102,12 +108,12 @@
 		tlb_write_indexed();
 	}
 	set_entryhi(old_ctx);
-	__restore_flags(flags);	
+	__restore_flags(flags);
 }
 
 
 /*
- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.  
+ * 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
@@ -209,7 +215,7 @@
 		set_entrylo1(0);
 		if(idx < 0)
 			goto finish;
-		/* Make sure all entries differ. */  
+		/* Make sure all entries differ. */
 		set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1)));
 		tlb_write_indexed();
 	finish:
@@ -299,7 +305,7 @@
 	/*
 	 * 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 
+	 * check exceptions due to duplicate TLB entries
 	 */
 	sb1_sanitize_tlb();
 
diff -urN linux-2.4.20-pre6/arch/mips/mm/tlbex-r3k.S linux-2.4.20-pre7/arch/mips/mm/tlbex-r3k.S
--- linux-2.4.20-pre6/arch/mips/mm/tlbex-r3k.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/tlbex-r3k.S	Thu Sep 12 20:01:40 2002
@@ -112,7 +112,7 @@
 	.set	push;       \
 	.set	reorder;    \
 	 lw	pte, (ptr); \
-	.set	pop; 
+	.set	pop;
 
 	/* Make PTE valid, store result in PTR. */
 #define PTE_MAKEVALID(pte, ptr) \
@@ -130,7 +130,7 @@
 	.set    reorder;    \
 	lw      pte, (ptr); \
 	.set    pop;
- 
+
 
 	/* Make PTE writable, update software status bits as well,
 	 * then store at PTR.
@@ -160,7 +160,7 @@
 	nop; \
 	jr	reg; \
 	 rfe
-			
+
 	.set	noreorder
 
 	.align	5
diff -urN linux-2.4.20-pre6/arch/mips/mm/tlbex-r4k.S linux-2.4.20-pre7/arch/mips/mm/tlbex-r4k.S
--- linux-2.4.20-pre6/arch/mips/mm/tlbex-r4k.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/tlbex-r4k.S	Thu Sep 12 20:01:40 2002
@@ -56,7 +56,7 @@
 #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
@@ -74,9 +74,9 @@
 	sll	k1, 2				# log2(sizeof(pgd_t)
 	addu	k1, k0, k1
 	lw	k1, (k1)
-#else 
+#else
 	lw	k1, pgd_current			# get pgd pointer
-#endif	
+#endif
 	mfc0	k0, CP0_BADVADDR		# Get faulting address
 	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
 
@@ -295,29 +295,6 @@
 	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
@@ -337,7 +314,7 @@
 	srl     ptr, 23;             \
 	sll     ptr, 2;              \
 	addu    ptr, scratch, ptr;   \
-	lw      ptr, (ptr);          
+	lw      ptr, (ptr);
 #else
 #define GET_PGD(scratch, ptr)    \
 	lw	ptr, pgd_current;
@@ -461,7 +438,7 @@
 	 tlbwi
 1:
 	nop
-	.set	mips3	
+	.set	mips3
 	eret
 	.set	mips0
 #endif
@@ -527,184 +504,3 @@
 	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 -urN linux-2.4.20-pre6/arch/mips/mm/umap.c linux-2.4.20-pre7/arch/mips/mm/umap.c
--- linux-2.4.20-pre6/arch/mips/mm/umap.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/mm/umap.c	Thu Sep 12 20:01:40 2002
@@ -53,7 +53,7 @@
 		address += PAGE_SIZE;
 		pte++;
 	} while (address < end);
-						  
+
 }
 
 static inline void
@@ -80,7 +80,7 @@
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
-		
+
 }
 
 /*
@@ -138,7 +138,7 @@
 
 /*
  * maps a range of vmalloc()ed memory into the requested pages. the old
- * mappings are removed. 
+ * mappings are removed.
  */
 static inline void
 vmap_pte_range (pte_t *pte, unsigned long address, unsigned long size, unsigned long vaddr)
@@ -147,7 +147,7 @@
 	pgd_t *vdir;
 	pmd_t *vpmd;
 	pte_t *vpte;
-	
+
 	address &= ~PMD_MASK;
 	end = address + size;
 	if (end > PMD_SIZE)
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/Makefile linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/Makefile
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,20 @@
+#
+# Makefile for Momentum Computer's Ocelot-G 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:= ocelot_g.o
+
+obj-y	 += gt-irq.o pci-irq.o pci.o int-handler.o irq.o prom.o reset.o setup.o
+
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/dbg_io.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/dbg_io.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/dbg_io.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/dbg_io.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,126 @@
+#include <linux/config.h>
+
+#if defined(CONFIG_REMOTE_DEBUG)
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+/* --- CONFIG --- */
+
+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                    OCELOT_SERIAL1_BASE
+#define         MAX_BAUD                OCELOT_BASE_BAUD
+
+/* === END OF CONFIG === */
+
+#define         REG_OFFSET              4
+
+/* 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);
+}
+
+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_38400,
+			  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 -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/gt-irq.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/gt-irq.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/gt-irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/gt-irq.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,294 @@
+/*
+ *
+ * Copyright 2002 Momentum Computer
+ * Author: mdharm@momenco.com
+ *
+ * arch/mips/momentum/ocelot_g/gt_irq.c
+ *     Interrupt routines for gt64240.  Currently it only handles timer irq.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/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 "gt64240.h"
+
+unsigned long bus_clock;
+
+/*
+ * 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);
+
+/*
+ * 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
+ */
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
+{
+	irq_handlers[int_cause][bit_num].routine = isr_ptr;
+}
+
+
+/*
+ * 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;
+}
+
+/*
+ * 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  */
+
+/*
+ * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
+ *
+ * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this
+ * routine can handle, for now.
+ *
+ * In the future, we'll route more interrupts to this pin, and that's why
+ * we keep this particular structure in the function.
+ */
+
+static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	uint32_t irq_src, irq_src_mask;
+	int handled;
+
+	/* get the low interrupt cause register */
+	GT_READ(LOW_INTERRUPT_CAUSE_REGISTER, &irq_src);
+
+	/* get the mask register for this pin */
+	GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, &irq_src_mask);
+
+	/* mask off only the interrupts we're interested in */
+	irq_src = irq_src & irq_src_mask;
+
+	handled = 0;
+
+	/* Check for timer interrupt */
+	if (irq_src & 0x00000100) {
+		handled = 1;
+		irq_src &= ~0x00000100;
+
+		/* Clear any pending cause bits */
+		GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
+
+		/* handle the timer call */
+		do_timer(regs);
+	}
+
+	if (irq_src) {
+		printk(KERN_INFO
+		       "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n",
+		       irq_src);
+	}
+}
+
+/*
+ * Interrupt handler for interrupts coming from the Galileo chip.
+ * It could be built in ethernet ports etc...
+ */
+static void gt64240_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;
+
+#if 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);
+#endif
+	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  */
+	}
+#if 0
+	GT_WRITE(GT_INTRCAUSE_OFS, 0);
+	GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+#endif
+
+#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
+}
+
+/*
+ * Initializes timer using galileo's built in timer.
+ */
+
+/*
+ * 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 gt64240_time_init(void)
+{
+	extern irq_desc_t irq_desc[NR_IRQS];
+	static struct irqaction timer;
+
+	/* Stop the timer -- we'll use timer #0 */
+	GT_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0);
+
+	/* Load timer value for 100 Hz */
+	GT_WRITE(TIMER_COUNTER0, bus_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 = &gt64240_p0int_irq;
+	timer.flags = SA_SHIRQ | SA_INTERRUPT;
+	timer.name = "timer";
+	timer.dev_id = NULL;
+	timer.next = NULL;
+	timer.mask = 0;
+	irq_desc[6].action = &timer;
+
+	enable_irq(6);
+
+	/* Clear any pending cause bits */
+	GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
+
+	/* Enable the interrupt for timer 0 */
+	GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1);
+
+	/* Enable the timer interrupt for GT-64240 pin P0_INT# */
+	GT_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100);
+
+	/* Configure and start the timer */
+	GT_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3);
+}
+
+void gt64240_irq_init(void)
+{
+#if CURRENTLY_UNUSED
+	int i, j;
+
+	/* 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 -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/gt64240.h linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/gt64240.h
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/gt64240.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/gt64240.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,1238 @@
+/* gt64240r.h - GT-64240 Internal registers definition file */
+
+/* Copyright - Galileo technology. */
+
+#ifndef __INCgt64240rh
+#define __INCgt64240rh
+
+#define GTREG(v)        (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \
+                        (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00)
+
+#if 0
+#define GTREG_SHORT(X)	(((X) << 8) | ((X) >> 8))
+
+#define LONG_GTREG(X)	((l64) \
+			(((X)&0x00000000000000ffULL) << 56) | \
+			(((X)&0x000000000000ff00ULL) << 40) | \
+			(((X)&0x0000000000ff0000ULL) << 24) | \
+			(((X)&0x00000000ff000000ULL) << 8)  | \
+			(((X)&0x000000ff00000000ULL) >> 8)  | \
+			(((X)&0x0000ff0000000000ULL) >> 24) | \
+			(((X)&0x00ff000000000000ULL) >> 40) | \
+			(((X)&0xff00000000000000ULL) >> 56))
+#endif
+
+#include "gt64240_dep.h"
+
+/****************************************/
+/* CPU Control Registers		*/
+/****************************************/
+
+#define CPU_CONFIGURATION					0x000
+#define CPU_MODE						0x120
+#define CPU_READ_RESPONSE_CROSSBAR_LOW				0x170
+#define CPU_READ_RESPONSE_CROSSBAR_HIGH				0x178
+
+/****************************************/
+/* Processor Address Space		*/
+/****************************************/
+
+/* Sdram's BAR'S */
+#define SCS_0_LOW_DECODE_ADDRESS				0x008
+#define SCS_0_HIGH_DECODE_ADDRESS				0x010
+#define SCS_1_LOW_DECODE_ADDRESS				0x208
+#define SCS_1_HIGH_DECODE_ADDRESS				0x210
+#define SCS_2_LOW_DECODE_ADDRESS				0x018
+#define SCS_2_HIGH_DECODE_ADDRESS				0x020
+#define SCS_3_LOW_DECODE_ADDRESS				0x218
+#define SCS_3_HIGH_DECODE_ADDRESS				0x220
+/* Devices BAR'S */
+#define CS_0_LOW_DECODE_ADDRESS					0x028
+#define CS_0_HIGH_DECODE_ADDRESS				0x030
+#define CS_1_LOW_DECODE_ADDRESS					0x228
+#define CS_1_HIGH_DECODE_ADDRESS				0x230
+#define CS_2_LOW_DECODE_ADDRESS					0x248
+#define CS_2_HIGH_DECODE_ADDRESS				0x250
+#define CS_3_LOW_DECODE_ADDRESS					0x038
+#define CS_3_HIGH_DECODE_ADDRESS				0x040
+#define BOOTCS_LOW_DECODE_ADDRESS				0x238
+#define BOOTCS_HIGH_DECODE_ADDRESS				0x240
+
+#define PCI_0I_O_LOW_DECODE_ADDRESS				0x048
+#define PCI_0I_O_HIGH_DECODE_ADDRESS				0x050
+#define PCI_0MEMORY0_LOW_DECODE_ADDRESS				0x058
+#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS			0x060
+#define PCI_0MEMORY1_LOW_DECODE_ADDRESS				0x080
+#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS			0x088
+#define PCI_0MEMORY2_LOW_DECODE_ADDRESS				0x258
+#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS			0x260
+#define PCI_0MEMORY3_LOW_DECODE_ADDRESS				0x280
+#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS			0x288
+
+#define PCI_1I_O_LOW_DECODE_ADDRESS				0x090
+#define PCI_1I_O_HIGH_DECODE_ADDRESS				0x098
+#define PCI_1MEMORY0_LOW_DECODE_ADDRESS				0x0a0
+#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS			0x0a8
+#define PCI_1MEMORY1_LOW_DECODE_ADDRESS				0x0b0
+#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS			0x0b8
+#define PCI_1MEMORY2_LOW_DECODE_ADDRESS				0x2a0
+#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS			0x2a8
+#define PCI_1MEMORY3_LOW_DECODE_ADDRESS				0x2b0
+#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS			0x2b8
+
+#define INTERNAL_SPACE_DECODE					0x068
+
+#define CPU_0_LOW_DECODE_ADDRESS                            0x290
+#define CPU_0_HIGH_DECODE_ADDRESS                           0x298
+#define CPU_1_LOW_DECODE_ADDRESS                            0x2c0
+#define CPU_1_HIGH_DECODE_ADDRESS                           0x2c8
+
+#define PCI_0I_O_ADDRESS_REMAP					0x0f0
+#define PCI_0MEMORY0_ADDRESS_REMAP  				0x0f8
+#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP				0x320
+#define PCI_0MEMORY1_ADDRESS_REMAP  				0x100
+#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP				0x328
+#define PCI_0MEMORY2_ADDRESS_REMAP  				0x2f8
+#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP				0x330
+#define PCI_0MEMORY3_ADDRESS_REMAP  			  	0x300
+#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP			   	0x338
+
+#define PCI_1I_O_ADDRESS_REMAP					0x108
+#define PCI_1MEMORY0_ADDRESS_REMAP  				0x110
+#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP				0x340
+#define PCI_1MEMORY1_ADDRESS_REMAP  				0x118
+#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP				0x348
+#define PCI_1MEMORY2_ADDRESS_REMAP  				0x310
+#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP				0x350
+#define PCI_1MEMORY3_ADDRESS_REMAP  				0x318
+#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP				0x358
+
+/****************************************/
+/* CPU Sync Barrier             		*/
+/****************************************/
+
+#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER			0x0c0
+#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER			0x0c8
+
+
+/****************************************/
+/* CPU Access Protect             		*/
+/****************************************/
+
+#define CPU_LOW_PROTECT_ADDRESS_0                           0X180
+#define CPU_HIGH_PROTECT_ADDRESS_0                          0X188
+#define CPU_LOW_PROTECT_ADDRESS_1                           0X190
+#define CPU_HIGH_PROTECT_ADDRESS_1                          0X198
+#define CPU_LOW_PROTECT_ADDRESS_2                           0X1a0
+#define CPU_HIGH_PROTECT_ADDRESS_2                          0X1a8
+#define CPU_LOW_PROTECT_ADDRESS_3                           0X1b0
+#define CPU_HIGH_PROTECT_ADDRESS_3                          0X1b8
+#define CPU_LOW_PROTECT_ADDRESS_4                           0X1c0
+#define CPU_HIGH_PROTECT_ADDRESS_4                          0X1c8
+#define CPU_LOW_PROTECT_ADDRESS_5                           0X1d0
+#define CPU_HIGH_PROTECT_ADDRESS_5                          0X1d8
+#define CPU_LOW_PROTECT_ADDRESS_6                           0X1e0
+#define CPU_HIGH_PROTECT_ADDRESS_6                          0X1e8
+#define CPU_LOW_PROTECT_ADDRESS_7                           0X1f0
+#define CPU_HIGH_PROTECT_ADDRESS_7                          0X1f8
+
+
+/****************************************/
+/*          Snoop Control          		*/
+/****************************************/
+
+#define SNOOP_BASE_ADDRESS_0                                0x380
+#define SNOOP_TOP_ADDRESS_0                                 0x388
+#define SNOOP_BASE_ADDRESS_1                                0x390
+#define SNOOP_TOP_ADDRESS_1                                 0x398
+#define SNOOP_BASE_ADDRESS_2                                0x3a0
+#define SNOOP_TOP_ADDRESS_2                                 0x3a8
+#define SNOOP_BASE_ADDRESS_3                                0x3b0
+#define SNOOP_TOP_ADDRESS_3                                 0x3b8
+
+/****************************************/
+/*          CPU Error Report       		*/
+/****************************************/
+
+#define CPU_ERROR_ADDRESS_LOW 				    0x070
+#define CPU_ERROR_ADDRESS_HIGH 				    0x078
+#define CPU_ERROR_DATA_LOW                                  0x128
+#define CPU_ERROR_DATA_HIGH                                 0x130
+#define CPU_ERROR_PARITY                                    0x138
+#define CPU_ERROR_CAUSE                                     0x140
+#define CPU_ERROR_MASK                                      0x148
+
+/****************************************/
+/*          Pslave Debug           		*/
+/****************************************/
+
+#define X_0_ADDRESS                                         0x360
+#define X_0_COMMAND_ID                                      0x368
+#define X_1_ADDRESS                                         0x370
+#define X_1_COMMAND_ID                                      0x378
+#define WRITE_DATA_LOW                                      0x3c0
+#define WRITE_DATA_HIGH                                     0x3c8
+#define WRITE_BYTE_ENABLE                                   0X3e0
+#define READ_DATA_LOW                                       0x3d0
+#define READ_DATA_HIGH                                      0x3d8
+#define READ_ID                                             0x3e8
+
+
+/****************************************/
+/* SDRAM and Device Address Space	*/
+/****************************************/
+
+
+/****************************************/
+/* SDRAM Configuration			*/
+/****************************************/
+
+#define SDRAM_CONFIGURATION	 			0x448
+#define SDRAM_OPERATION_MODE				0x474
+#define SDRAM_ADDRESS_DECODE				0x47C
+#define SDRAM_TIMING_PARAMETERS                         0x4b4
+#define SDRAM_UMA_CONTROL                               0x4a4
+#define SDRAM_CROSS_BAR_CONTROL_LOW                     0x4a8
+#define SDRAM_CROSS_BAR_CONTROL_HIGH                    0x4ac
+#define SDRAM_CROSS_BAR_TIMEOUT                         0x4b0
+
+
+/****************************************/
+/* SDRAM Parameters			*/
+/****************************************/
+
+#define SDRAM_BANK0PARAMETERS				0x44C
+#define SDRAM_BANK1PARAMETERS				0x450
+#define SDRAM_BANK2PARAMETERS				0x454
+#define SDRAM_BANK3PARAMETERS				0x458
+
+
+/****************************************/
+/* SDRAM Error Report 			*/
+/****************************************/
+
+#define SDRAM_ERROR_DATA_LOW                            0x484
+#define SDRAM_ERROR_DATA_HIGH                           0x480
+#define SDRAM_AND_DEVICE_ERROR_ADDRESS                  0x490
+#define SDRAM_RECEIVED_ECC                              0x488
+#define SDRAM_CALCULATED_ECC                            0x48c
+#define SDRAM_ECC_CONTROL                               0x494
+#define SDRAM_ECC_ERROR_COUNTER                         0x498
+
+
+/****************************************/
+/* SDunit Debug (for internal use)	*/
+/****************************************/
+
+#define X0_ADDRESS                                      0x500
+#define X0_COMMAND_AND_ID                               0x504
+#define X0_WRITE_DATA_LOW                               0x508
+#define X0_WRITE_DATA_HIGH                              0x50c
+#define X0_WRITE_BYTE_ENABLE                            0x518
+#define X0_READ_DATA_LOW                                0x510
+#define X0_READ_DATA_HIGH                               0x514
+#define X0_READ_ID                                      0x51c
+#define X1_ADDRESS                                      0x520
+#define X1_COMMAND_AND_ID                               0x524
+#define X1_WRITE_DATA_LOW                               0x528
+#define X1_WRITE_DATA_HIGH                              0x52c
+#define X1_WRITE_BYTE_ENABLE                            0x538
+#define X1_READ_DATA_LOW                                0x530
+#define X1_READ_DATA_HIGH                               0x534
+#define X1_READ_ID                                      0x53c
+#define X0_SNOOP_ADDRESS                                0x540
+#define X0_SNOOP_COMMAND                                0x544
+#define X1_SNOOP_ADDRESS                                0x548
+#define X1_SNOOP_COMMAND                                0x54c
+
+
+/****************************************/
+/* Device Parameters			*/
+/****************************************/
+
+#define DEVICE_BANK0PARAMETERS				0x45c
+#define DEVICE_BANK1PARAMETERS				0x460
+#define DEVICE_BANK2PARAMETERS				0x464
+#define DEVICE_BANK3PARAMETERS				0x468
+#define DEVICE_BOOT_BANK_PARAMETERS			0x46c
+#define DEVICE_CONTROL                                  0x4c0
+#define DEVICE_CROSS_BAR_CONTROL_LOW                    0x4c8
+#define DEVICE_CROSS_BAR_CONTROL_HIGH                   0x4cc
+#define DEVICE_CROSS_BAR_TIMEOUT                        0x4c4
+
+
+/****************************************/
+/* Device Interrupt 			*/
+/****************************************/
+
+#define DEVICE_INTERRUPT_CAUSE                              0x4d0
+#define DEVICE_INTERRUPT_MASK                               0x4d4
+#define DEVICE_ERROR_ADDRESS                                0x4d8
+
+/****************************************/
+/* DMA Record				*/
+/****************************************/
+
+#define CHANNEL0_DMA_BYTE_COUNT					0x800
+#define CHANNEL1_DMA_BYTE_COUNT	 				0x804
+#define CHANNEL2_DMA_BYTE_COUNT	 				0x808
+#define CHANNEL3_DMA_BYTE_COUNT	 				0x80C
+#define CHANNEL4_DMA_BYTE_COUNT					0x900
+#define CHANNEL5_DMA_BYTE_COUNT	 				0x904
+#define CHANNEL6_DMA_BYTE_COUNT	 				0x908
+#define CHANNEL7_DMA_BYTE_COUNT	 				0x90C
+#define CHANNEL0_DMA_SOURCE_ADDRESS				0x810
+#define CHANNEL1_DMA_SOURCE_ADDRESS				0x814
+#define CHANNEL2_DMA_SOURCE_ADDRESS				0x818
+#define CHANNEL3_DMA_SOURCE_ADDRESS				0x81C
+#define CHANNEL4_DMA_SOURCE_ADDRESS				0x910
+#define CHANNEL5_DMA_SOURCE_ADDRESS				0x914
+#define CHANNEL6_DMA_SOURCE_ADDRESS				0x918
+#define CHANNEL7_DMA_SOURCE_ADDRESS				0x91C
+#define CHANNEL0_DMA_DESTINATION_ADDRESS			0x820
+#define CHANNEL1_DMA_DESTINATION_ADDRESS			0x824
+#define CHANNEL2_DMA_DESTINATION_ADDRESS			0x828
+#define CHANNEL3_DMA_DESTINATION_ADDRESS			0x82C
+#define CHANNEL4_DMA_DESTINATION_ADDRESS			0x920
+#define CHANNEL5_DMA_DESTINATION_ADDRESS			0x924
+#define CHANNEL6_DMA_DESTINATION_ADDRESS			0x928
+#define CHANNEL7_DMA_DESTINATION_ADDRESS			0x92C
+#define CHANNEL0NEXT_RECORD_POINTER				0x830
+#define CHANNEL1NEXT_RECORD_POINTER				0x834
+#define CHANNEL2NEXT_RECORD_POINTER				0x838
+#define CHANNEL3NEXT_RECORD_POINTER				0x83C
+#define CHANNEL4NEXT_RECORD_POINTER				0x930
+#define CHANNEL5NEXT_RECORD_POINTER				0x934
+#define CHANNEL6NEXT_RECORD_POINTER				0x938
+#define CHANNEL7NEXT_RECORD_POINTER				0x93C
+#define CHANNEL0CURRENT_DESCRIPTOR_POINTER			0x870
+#define CHANNEL1CURRENT_DESCRIPTOR_POINTER			0x874
+#define CHANNEL2CURRENT_DESCRIPTOR_POINTER			0x878
+#define CHANNEL3CURRENT_DESCRIPTOR_POINTER			0x87C
+#define CHANNEL4CURRENT_DESCRIPTOR_POINTER			0x970
+#define CHANNEL5CURRENT_DESCRIPTOR_POINTER			0x974
+#define CHANNEL6CURRENT_DESCRIPTOR_POINTER			0x978
+#define CHANNEL7CURRENT_DESCRIPTOR_POINTER			0x97C
+#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS			0x890
+#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS			0x894
+#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS			0x898
+#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS			0x89c
+#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS			0x990
+#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS			0x994
+#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS			0x998
+#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS			0x99c
+#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8a0
+#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8a4
+#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8a8
+#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x8ac
+#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9a0
+#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9a4
+#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9a8
+#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS		0x9ac
+#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8b0
+#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8b4
+#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8b8
+#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x8bc
+#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9b0
+#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9b4
+#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9b8
+#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS	0x9bc
+
+/****************************************/
+/* DMA Channel Control			*/
+/****************************************/
+
+#define CHANNEL0CONTROL 					0x840
+#define CHANNEL0CONTROL_HIGH					0x880
+
+#define CHANNEL1CONTROL 					0x844
+#define CHANNEL1CONTROL_HIGH					0x884
+
+#define CHANNEL2CONTROL 					0x848
+#define CHANNEL2CONTROL_HIGH					0x888
+
+#define CHANNEL3CONTROL 					0x84C
+#define CHANNEL3CONTROL_HIGH					0x88C
+
+#define CHANNEL4CONTROL 					0x940
+#define CHANNEL4CONTROL_HIGH					0x980
+
+#define CHANNEL5CONTROL 					0x944
+#define CHANNEL5CONTROL_HIGH					0x984
+
+#define CHANNEL6CONTROL 					0x948
+#define CHANNEL6CONTROL_HIGH					0x988
+
+#define CHANNEL7CONTROL 					0x94C
+#define CHANNEL7CONTROL_HIGH					0x98C
+
+
+/****************************************/
+/* DMA Arbiter				*/
+/****************************************/
+
+#define ARBITER_CONTROL_0_3					0x860
+#define ARBITER_CONTROL_4_7					0x960
+
+
+/****************************************/
+/* DMA Interrupt			*/
+/****************************************/
+
+#define CHANELS0_3_INTERRUPT_CAUSE				0x8c0
+#define CHANELS0_3_INTERRUPT_MASK				0x8c4
+#define CHANELS0_3_ERROR_ADDRESS				0x8c8
+#define CHANELS0_3_ERROR_SELECT					0x8cc
+#define CHANELS4_7_INTERRUPT_CAUSE				0x9c0
+#define CHANELS4_7_INTERRUPT_MASK				0x9c4
+#define CHANELS4_7_ERROR_ADDRESS				0x9c8
+#define CHANELS4_7_ERROR_SELECT					0x9cc
+
+
+/****************************************/
+/* DMA Debug (for internal use)         */
+/****************************************/
+
+#define DMA_X0_ADDRESS                                      0x8e0
+#define DMA_X0_COMMAND_AND_ID                               0x8e4
+#define DMA_X0_WRITE_DATA_LOW                               0x8e8
+#define DMA_X0_WRITE_DATA_HIGH                              0x8ec
+#define DMA_X0_WRITE_BYTE_ENABLE                            0x8f8
+#define DMA_X0_READ_DATA_LOW                                0x8f0
+#define DMA_X0_READ_DATA_HIGH                               0x8f4
+#define DMA_X0_READ_ID                                      0x8fc
+#define DMA_X1_ADDRESS                                      0x9e0
+#define DMA_X1_COMMAND_AND_ID                               0x9e4
+#define DMA_X1_WRITE_DATA_LOW                               0x9e8
+#define DMA_X1_WRITE_DATA_HIGH                              0x9ec
+#define DMA_X1_WRITE_BYTE_ENABLE                            0x9f8
+#define DMA_X1_READ_DATA_LOW                                0x9f0
+#define DMA_X1_READ_DATA_HIGH                               0x9f4
+#define DMA_X1_READ_ID                                      0x9fc
+
+/****************************************/
+/* Timer_Counter 						*/
+/****************************************/
+
+#define TIMER_COUNTER0						0x850
+#define TIMER_COUNTER1						0x854
+#define TIMER_COUNTER2						0x858
+#define TIMER_COUNTER3						0x85C
+#define TIMER_COUNTER_0_3_CONTROL				0x864
+#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE			0x868
+#define TIMER_COUNTER_0_3_INTERRUPT_MASK      			0x86c
+#define TIMER_COUNTER4						0x950
+#define TIMER_COUNTER5						0x954
+#define TIMER_COUNTER6						0x958
+#define TIMER_COUNTER7						0x95C
+#define TIMER_COUNTER_4_7_CONTROL				0x964
+#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE			0x968
+#define TIMER_COUNTER_4_7_INTERRUPT_MASK      			0x96c
+
+/****************************************/
+/* PCI Slave Address Decoding           */
+/****************************************/
+
+#define PCI_0SCS_0_BANK_SIZE					0xc08
+#define PCI_1SCS_0_BANK_SIZE					0xc88
+#define PCI_0SCS_1_BANK_SIZE					0xd08
+#define PCI_1SCS_1_BANK_SIZE					0xd88
+#define PCI_0SCS_2_BANK_SIZE					0xc0c
+#define PCI_1SCS_2_BANK_SIZE					0xc8c
+#define PCI_0SCS_3_BANK_SIZE					0xd0c
+#define PCI_1SCS_3_BANK_SIZE					0xd8c
+#define PCI_0CS_0_BANK_SIZE				    	0xc10
+#define PCI_1CS_0_BANK_SIZE				    	0xc90
+#define PCI_0CS_1_BANK_SIZE				    	0xd10
+#define PCI_1CS_1_BANK_SIZE				    	0xd90
+#define PCI_0CS_2_BANK_SIZE				    	0xd18
+#define PCI_1CS_2_BANK_SIZE				    	0xd98
+#define PCI_0CS_3_BANK_SIZE			       		0xc14
+#define PCI_1CS_3_BANK_SIZE			       		0xc94
+#define PCI_0CS_BOOT_BANK_SIZE					0xd14
+#define PCI_1CS_BOOT_BANK_SIZE					0xd94
+#define PCI_0P2P_MEM0_BAR_SIZE                              0xd1c
+#define PCI_1P2P_MEM0_BAR_SIZE                              0xd9c
+#define PCI_0P2P_MEM1_BAR_SIZE                              0xd20
+#define PCI_1P2P_MEM1_BAR_SIZE                              0xda0
+#define PCI_0P2P_I_O_BAR_SIZE                               0xd24
+#define PCI_1P2P_I_O_BAR_SIZE                               0xda4
+#define PCI_0CPU_BAR_SIZE                                   0xd28
+#define PCI_1CPU_BAR_SIZE                                   0xda8
+#define PCI_0DAC_SCS_0_BANK_SIZE                            0xe00
+#define PCI_1DAC_SCS_0_BANK_SIZE                            0xe80
+#define PCI_0DAC_SCS_1_BANK_SIZE                            0xe04
+#define PCI_1DAC_SCS_1_BANK_SIZE                            0xe84
+#define PCI_0DAC_SCS_2_BANK_SIZE                            0xe08
+#define PCI_1DAC_SCS_2_BANK_SIZE                            0xe88
+#define PCI_0DAC_SCS_3_BANK_SIZE                            0xe0c
+#define PCI_1DAC_SCS_3_BANK_SIZE                            0xe8c
+#define PCI_0DAC_CS_0_BANK_SIZE                             0xe10
+#define PCI_1DAC_CS_0_BANK_SIZE                             0xe90
+#define PCI_0DAC_CS_1_BANK_SIZE                             0xe14
+#define PCI_1DAC_CS_1_BANK_SIZE                             0xe94
+#define PCI_0DAC_CS_2_BANK_SIZE                             0xe18
+#define PCI_1DAC_CS_2_BANK_SIZE                             0xe98
+#define PCI_0DAC_CS_3_BANK_SIZE                             0xe1c
+#define PCI_1DAC_CS_3_BANK_SIZE                             0xe9c
+#define PCI_0DAC_BOOTCS_BANK_SIZE                           0xe20
+#define PCI_1DAC_BOOTCS_BANK_SIZE                           0xea0
+#define PCI_0DAC_P2P_MEM0_BAR_SIZE                          0xe24
+#define PCI_1DAC_P2P_MEM0_BAR_SIZE                          0xea4
+#define PCI_0DAC_P2P_MEM1_BAR_SIZE                          0xe28
+#define PCI_1DAC_P2P_MEM1_BAR_SIZE                          0xea8
+#define PCI_0DAC_CPU_BAR_SIZE                               0xe2c
+#define PCI_1DAC_CPU_BAR_SIZE                               0xeac
+#define PCI_0EXPANSION_ROM_BAR_SIZE                         0xd2c
+#define PCI_1EXPANSION_ROM_BAR_SIZE                         0xdac
+#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 			0xc3c
+#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 			0xcbc
+#define PCI_0SCS_0_BASE_ADDRESS_REMAP				0xc48
+#define PCI_1SCS_0_BASE_ADDRESS_REMAP				0xcc8
+#define PCI_0SCS_1_BASE_ADDRESS_REMAP				0xd48
+#define PCI_1SCS_1_BASE_ADDRESS_REMAP				0xdc8
+#define PCI_0SCS_2_BASE_ADDRESS_REMAP				0xc4c
+#define PCI_1SCS_2_BASE_ADDRESS_REMAP				0xccc
+#define PCI_0SCS_3_BASE_ADDRESS_REMAP				0xd4c
+#define PCI_1SCS_3_BASE_ADDRESS_REMAP				0xdcc
+#define PCI_0CS_0_BASE_ADDRESS_REMAP				0xc50
+#define PCI_1CS_0_BASE_ADDRESS_REMAP				0xcd0
+#define PCI_0CS_1_BASE_ADDRESS_REMAP				0xd50
+#define PCI_1CS_1_BASE_ADDRESS_REMAP				0xdd0
+#define PCI_0CS_2_BASE_ADDRESS_REMAP				0xd58
+#define PCI_1CS_2_BASE_ADDRESS_REMAP				0xdd8
+#define PCI_0CS_3_BASE_ADDRESS_REMAP           			0xc54
+#define PCI_1CS_3_BASE_ADDRESS_REMAP           			0xcd4
+#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP      			0xd54
+#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP      			0xdd4
+#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW                0xd5c
+#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW                0xddc
+#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH               0xd60
+#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH               0xde0
+#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW                0xd64
+#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW                0xde4
+#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH               0xd68
+#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH               0xde8
+#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP                     0xd6c
+#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP                     0xdec
+#define PCI_0CPU_BASE_ADDRESS_REMAP                         0xd70
+#define PCI_1CPU_BASE_ADDRESS_REMAP                         0xdf0
+#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP                   0xf00
+#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP                   0xff0
+#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP                   0xf04
+#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP                   0xf84
+#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP                   0xf08
+#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP                   0xf88
+#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP                   0xf0c
+#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP                   0xf8c
+#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP                    0xf10
+#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP                    0xf90
+#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP                    0xf14
+#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP                    0xf94
+#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP                    0xf18
+#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP                    0xf98
+#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP                    0xf1c
+#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP                    0xf9c
+#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP                  0xf20
+#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP                  0xfa0
+#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW            0xf24
+#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW            0xfa4
+#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH           0xf28
+#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH           0xfa8
+#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW            0xf2c
+#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW            0xfac
+#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH           0xf30
+#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH           0xfb0
+#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP                     0xf34
+#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP                     0xfb4
+#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP               0xf38
+#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP               0xfb8
+#define PCI_0ADDRESS_DECODE_CONTROL                         0xd3c
+#define PCI_1ADDRESS_DECODE_CONTROL                         0xdbc
+
+/****************************************/
+/* PCI Control                          */
+/****************************************/
+
+#define PCI_0COMMAND						0xc00
+#define PCI_1COMMAND						0xc80
+#define PCI_0MODE                                           0xd00
+#define PCI_1MODE                                           0xd80
+#define PCI_0TIMEOUT_RETRY					0xc04
+#define PCI_1TIMEOUT_RETRY					0xc84
+#define PCI_0READ_BUFFER_DISCARD_TIMER                      0xd04
+#define PCI_1READ_BUFFER_DISCARD_TIMER                      0xd84
+#define MSI_0TRIGGER_TIMER                                  0xc38
+#define MSI_1TRIGGER_TIMER                                  0xcb8
+#define PCI_0ARBITER_CONTROL                                0x1d00
+#define PCI_1ARBITER_CONTROL                                0x1d80
+/* changing untill here */
+#define PCI_0CROSS_BAR_CONTROL_LOW                           0x1d08
+#define PCI_0CROSS_BAR_CONTROL_HIGH                          0x1d0c
+#define PCI_0CROSS_BAR_TIMEOUT                               0x1d04
+#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW             0x1d18
+#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH            0x1d1c
+#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER                   0x1d10
+#define PCI_0P2P_CONFIGURATION                               0x1d14
+#define PCI_0ACCESS_CONTROL_BASE_0_LOW                       0x1e00
+#define PCI_0ACCESS_CONTROL_BASE_0_HIGH                      0x1e04
+#define PCI_0ACCESS_CONTROL_TOP_0                            0x1e08
+#define PCI_0ACCESS_CONTROL_BASE_1_LOW                       0c1e10
+#define PCI_0ACCESS_CONTROL_BASE_1_HIGH                      0x1e14
+#define PCI_0ACCESS_CONTROL_TOP_1                            0x1e18
+#define PCI_0ACCESS_CONTROL_BASE_2_LOW                       0c1e20
+#define PCI_0ACCESS_CONTROL_BASE_2_HIGH                      0x1e24
+#define PCI_0ACCESS_CONTROL_TOP_2                            0x1e28
+#define PCI_0ACCESS_CONTROL_BASE_3_LOW                       0c1e30
+#define PCI_0ACCESS_CONTROL_BASE_3_HIGH                      0x1e34
+#define PCI_0ACCESS_CONTROL_TOP_3                            0x1e38
+#define PCI_0ACCESS_CONTROL_BASE_4_LOW                       0c1e40
+#define PCI_0ACCESS_CONTROL_BASE_4_HIGH                      0x1e44
+#define PCI_0ACCESS_CONTROL_TOP_4                            0x1e48
+#define PCI_0ACCESS_CONTROL_BASE_5_LOW                       0c1e50
+#define PCI_0ACCESS_CONTROL_BASE_5_HIGH                      0x1e54
+#define PCI_0ACCESS_CONTROL_TOP_5                            0x1e58
+#define PCI_0ACCESS_CONTROL_BASE_6_LOW                       0c1e60
+#define PCI_0ACCESS_CONTROL_BASE_6_HIGH                      0x1e64
+#define PCI_0ACCESS_CONTROL_TOP_6                            0x1e68
+#define PCI_0ACCESS_CONTROL_BASE_7_LOW                       0c1e70
+#define PCI_0ACCESS_CONTROL_BASE_7_HIGH                      0x1e74
+#define PCI_0ACCESS_CONTROL_TOP_7                            0x1e78
+#define PCI_1CROSS_BAR_CONTROL_LOW                           0x1d88
+#define PCI_1CROSS_BAR_CONTROL_HIGH                          0x1d8c
+#define PCI_1CROSS_BAR_TIMEOUT                               0x1d84
+#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW             0x1d98
+#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH            0x1d9c
+#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER                   0x1d90
+#define PCI_1P2P_CONFIGURATION                               0x1d94
+#define PCI_1ACCESS_CONTROL_BASE_0_LOW                       0x1e80
+#define PCI_1ACCESS_CONTROL_BASE_0_HIGH                      0x1e84
+#define PCI_1ACCESS_CONTROL_TOP_0                            0x1e88
+#define PCI_1ACCESS_CONTROL_BASE_1_LOW                       0c1e90
+#define PCI_1ACCESS_CONTROL_BASE_1_HIGH                      0x1e94
+#define PCI_1ACCESS_CONTROL_TOP_1                            0x1e98
+#define PCI_1ACCESS_CONTROL_BASE_2_LOW                       0c1ea0
+#define PCI_1ACCESS_CONTROL_BASE_2_HIGH                      0x1ea4
+#define PCI_1ACCESS_CONTROL_TOP_2                            0x1ea8
+#define PCI_1ACCESS_CONTROL_BASE_3_LOW                       0c1eb0
+#define PCI_1ACCESS_CONTROL_BASE_3_HIGH                      0x1eb4
+#define PCI_1ACCESS_CONTROL_TOP_3                            0x1eb8
+#define PCI_1ACCESS_CONTROL_BASE_4_LOW                       0c1ec0
+#define PCI_1ACCESS_CONTROL_BASE_4_HIGH                      0x1ec4
+#define PCI_1ACCESS_CONTROL_TOP_4                            0x1ec8
+#define PCI_1ACCESS_CONTROL_BASE_5_LOW                       0c1ed0
+#define PCI_1ACCESS_CONTROL_BASE_5_HIGH                      0x1ed4
+#define PCI_1ACCESS_CONTROL_TOP_5                            0x1ed8
+#define PCI_1ACCESS_CONTROL_BASE_6_LOW                       0c1ee0
+#define PCI_1ACCESS_CONTROL_BASE_6_HIGH                      0x1ee4
+#define PCI_1ACCESS_CONTROL_TOP_6                            0x1ee8
+#define PCI_1ACCESS_CONTROL_BASE_7_LOW                       0c1ef0
+#define PCI_1ACCESS_CONTROL_BASE_7_HIGH                      0x1ef4
+#define PCI_1ACCESS_CONTROL_TOP_7                            0x1ef8
+
+/****************************************/
+/* PCI Snoop Control                    */
+/****************************************/
+
+#define PCI_0SNOOP_CONTROL_BASE_0_LOW                        0x1f00
+#define PCI_0SNOOP_CONTROL_BASE_0_HIGH                       0x1f04
+#define PCI_0SNOOP_CONTROL_TOP_0                             0x1f08
+#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW                      0x1f10
+#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH                     0x1f14
+#define PCI_0SNOOP_CONTROL_TOP_1                             0x1f18
+#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW                      0x1f20
+#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH                     0x1f24
+#define PCI_0SNOOP_CONTROL_TOP_2                             0x1f28
+#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW                      0x1f30
+#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH                     0x1f34
+#define PCI_0SNOOP_CONTROL_TOP_3                             0x1f38
+#define PCI_1SNOOP_CONTROL_BASE_0_LOW                        0x1f80
+#define PCI_1SNOOP_CONTROL_BASE_0_HIGH                       0x1f84
+#define PCI_1SNOOP_CONTROL_TOP_0                             0x1f88
+#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW                      0x1f90
+#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH                     0x1f94
+#define PCI_1SNOOP_CONTROL_TOP_1                             0x1f98
+#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW                      0x1fa0
+#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH                     0x1fa4
+#define PCI_1SNOOP_CONTROL_TOP_2                             0x1fa8
+#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW                      0x1fb0
+#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH                     0x1fb4
+#define PCI_1SNOOP_CONTROL_TOP_3                             0x1fb8
+
+/****************************************/
+/* PCI Configuration Address            */
+/****************************************/
+
+#define PCI_0CONFIGURATION_ADDRESS 				0xcf8
+#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER           	0xcfc
+#define PCI_1CONFIGURATION_ADDRESS 				0xc78
+#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER           	0xc7c
+#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER		0xc34
+#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER		0xcb4
+
+/****************************************/
+/* PCI Error Report                     */
+/****************************************/
+
+#define PCI_0SERR_MASK						 0xc28
+#define PCI_0ERROR_ADDRESS_LOW                               0x1d40
+#define PCI_0ERROR_ADDRESS_HIGH                              0x1d44
+#define PCI_0ERROR_DATA_LOW                                  0x1d48
+#define PCI_0ERROR_DATA_HIGH                                 0x1d4c
+#define PCI_0ERROR_COMMAND                                   0x1d50
+#define PCI_0ERROR_CAUSE                                     0x1d58
+#define PCI_0ERROR_MASK                                      0x1d5c
+
+#define PCI_1SERR_MASK						 0xca8
+#define PCI_1ERROR_ADDRESS_LOW                               0x1dc0
+#define PCI_1ERROR_ADDRESS_HIGH                              0x1dc4
+#define PCI_1ERROR_DATA_LOW                                  0x1dc8
+#define PCI_1ERROR_DATA_HIGH                                 0x1dcc
+#define PCI_1ERROR_COMMAND                                   0x1dd0
+#define PCI_1ERROR_CAUSE                                     0x1dd8
+#define PCI_1ERROR_MASK                                      0x1ddc
+
+
+/****************************************/
+/* Lslave Debug  (for internal use)     */
+/****************************************/
+
+#define L_SLAVE_X0_ADDRESS                                  0x1d20
+#define L_SLAVE_X0_COMMAND_AND_ID                           0x1d24
+#define L_SLAVE_X1_ADDRESS                                  0x1d28
+#define L_SLAVE_X1_COMMAND_AND_ID                           0x1d2c
+#define L_SLAVE_WRITE_DATA_LOW                              0x1d30
+#define L_SLAVE_WRITE_DATA_HIGH                             0x1d34
+#define L_SLAVE_WRITE_BYTE_ENABLE                           0x1d60
+#define L_SLAVE_READ_DATA_LOW                               0x1d38
+#define L_SLAVE_READ_DATA_HIGH                              0x1d3c
+#define L_SLAVE_READ_ID                                     0x1d64
+
+/****************************************/
+/* PCI Configuration Function 0         */
+/****************************************/
+
+#define PCI_DEVICE_AND_VENDOR_ID 				0x000
+#define PCI_STATUS_AND_COMMAND					0x004
+#define PCI_CLASS_CODE_AND_REVISION_ID			        0x008
+#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 		0x00C
+#define PCI_SCS_0_BASE_ADDRESS	    				0x010
+#define PCI_SCS_1_BASE_ADDRESS 					0x014
+#define PCI_SCS_2_BASE_ADDRESS 					0x018
+#define PCI_SCS_3_BASE_ADDRESS      				0x01C
+#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS	0x020
+#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS		0x024
+#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID		0x02C
+#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER			0x030
+#define PCI_CAPABILTY_LIST_POINTER                          0x034
+#define PCI_INTERRUPT_PIN_AND_LINE 			    0x03C
+#define PCI_POWER_MANAGEMENT_CAPABILITY                     0x040
+#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL             0x044
+#define PCI_VPD_ADDRESS                                     0x048
+#define PCI_VPD_DATA                                        0X04c
+#define PCI_MSI_MESSAGE_CONTROL                             0x050
+#define PCI_MSI_MESSAGE_ADDRESS                             0x054
+#define PCI_MSI_MESSAGE_UPPER_ADDRESS                       0x058
+#define PCI_MSI_MESSAGE_DATA                                0x05c
+#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY                 0x058
+
+/****************************************/
+/* PCI Configuration Function 1         */
+/****************************************/
+
+#define PCI_CS_0_BASE_ADDRESS	    				0x110
+#define PCI_CS_1_BASE_ADDRESS 					0x114
+#define PCI_CS_2_BASE_ADDRESS 					0x118
+#define PCI_CS_3_BASE_ADDRESS     				0x11c
+#define PCI_BOOTCS_BASE_ADDRESS                     	    0x120
+
+/****************************************/
+/* PCI Configuration Function 2         */
+/****************************************/
+
+#define PCI_P2P_MEM0_BASE_ADDRESS	    			0x210
+#define PCI_P2P_MEM1_BASE_ADDRESS 				0x214
+#define PCI_P2P_I_O_BASE_ADDRESS 				0x218
+#define PCI_CPU_BASE_ADDRESS      				0x21c
+
+/****************************************/
+/* PCI Configuration Function 4         */
+/****************************************/
+
+#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 				0x410
+#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH			 	0x414
+#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW   			0x418
+#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH  		    0x41c
+#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW              	    0x420
+#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH             	    0x424
+
+
+/****************************************/
+/* PCI Configuration Function 5         */
+/****************************************/
+
+#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 				0x510
+#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH				0x514
+#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW   		 	0x518
+#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH  		 	0x51c
+#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW              	    0x520
+#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH             	    0x524
+
+
+/****************************************/
+/* PCI Configuration Function 6         */
+/****************************************/
+
+#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 				0x610
+#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH				0x614
+#define PCI_DAC_CS_1_BASE_ADDRESS_LOW   			0x618
+#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH  			0x61c
+#define PCI_DAC_CS_2_BASE_ADDRESS_LOW            	        0x620
+#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH           	        0x624
+
+/****************************************/
+/* PCI Configuration Function 7         */
+/****************************************/
+
+#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 				0x710
+#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH			 	0x714
+#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW   		 	0x718
+#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH  			0x71c
+#define PCI_DAC_CPU_BASE_ADDRESS_LOW            	        0x720
+#define PCI_DAC_CPU_BASE_ADDRESS_HIGH           	        0x724
+
+/****************************************/
+/* Interrupts	  			*/
+/****************************************/
+
+#define LOW_INTERRUPT_CAUSE_REGISTER   				0xc18
+#define HIGH_INTERRUPT_CAUSE_REGISTER				0xc68
+#define CPU_INTERRUPT_MASK_REGISTER_LOW				0xc1c
+#define CPU_INTERRUPT_MASK_REGISTER_HIGH			0xc6c
+#define CPU_SELECT_CAUSE_REGISTER				0xc70
+#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW			0xc24
+#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH			0xc64
+#define PCI_0SELECT_CAUSE                                   0xc74
+#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW			0xca4
+#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH			0xce4
+#define PCI_1SELECT_CAUSE                                   0xcf4
+#define CPU_INT_0_MASK                                      0xe60
+#define CPU_INT_1_MASK                                      0xe64
+#define CPU_INT_2_MASK                                      0xe68
+#define CPU_INT_3_MASK                                      0xe6c
+
+/****************************************/
+/* I20 Support registers		*/
+/****************************************/
+
+#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE			0x010
+#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE  			0x014
+#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 			0x018
+#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE  			0x01C
+#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE  			0x020
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE  		0x024
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE		0x028
+#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 			0x02C
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE   		0x030
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE   		0x034
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE  		0x040
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE   	0x044
+#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 			0x050
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 			0x054
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE		0x060
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE  		0x064
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 		0x068
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 		0x06C
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE		0x070
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE		0x074
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE		0x0F8
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE		0x0FC
+
+#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE				0x090
+#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE  				0x094
+#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 				0x098
+#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE  				0x09C
+#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE  				0x0A0
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE  		0x0A4
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE			0x0A8
+#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 				0x0AC
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE   		0x0B0
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE   		0x0B4
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE  		0x0C0
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE   	0x0C4
+#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 				0x0D0
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 				0x0D4
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE		0x0E0
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE  		0x0E4
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 		0x0E8
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 		0x0EC
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE		0x0F0
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE		0x0F4
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE		0x078
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE		0x07C
+
+#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE				0X1C10
+#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE  				0X1C14
+#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 				0X1C18
+#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE  				0X1C1C
+#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE  				0X1C20
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE  		0X1C24
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE			0X1C28
+#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 				0X1C2C
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE   		0X1C30
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE   		0X1C34
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE  		0X1C40
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE   	0X1C44
+#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 				0X1C50
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 				0X1C54
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE		0X1C60
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE  		0X1C64
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 		0X1C68
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 		0X1C6C
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE		0X1C70
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE		0X1C74
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE		0X1CF8
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE		0X1CFC
+
+#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE				0X1C90
+#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE  				0X1C94
+#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 				0X1C98
+#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE  				0X1C9C
+#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE  				0X1CA0
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE  		0X1CA4
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE			0X1CA8
+#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 				0X1CAC
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE   		0X1CB0
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE   		0X1CB4
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE  		0X1CC0
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE   	0X1CC4
+#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 				0X1CD0
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 				0X1CD4
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE		0X1CE0
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE  		0X1CE4
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 		0X1CE8
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 		0X1CEC
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE		0X1CF0
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE		0X1CF4
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE		0X1C78
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE		0X1C7C
+
+/****************************************/
+/* Communication Unit Registers         */
+/****************************************/
+
+#define ETHERNET_0_ADDRESS_CONTROL_LOW
+#define ETHERNET_0_ADDRESS_CONTROL_HIGH                     0xf204
+#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS          0xf208
+#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS         0xf20c
+#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS      0xf210
+#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS     0xf214
+#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS              0xf218
+#define ETHERNET_1_ADDRESS_CONTROL_LOW                      0xf220
+#define ETHERNET_1_ADDRESS_CONTROL_HIGH                     0xf224
+#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS          0xf228
+#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS         0xf22c
+#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS      0xf230
+#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS     0xf234
+#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS              0xf238
+#define ETHERNET_2_ADDRESS_CONTROL_LOW                      0xf240
+#define ETHERNET_2_ADDRESS_CONTROL_HIGH                     0xf244
+#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS          0xf248
+#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS         0xf24c
+#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS      0xf250
+#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS     0xf254
+#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS              0xf258
+#define MPSC_0_ADDRESS_CONTROL_LOW                          0xf280
+#define MPSC_0_ADDRESS_CONTROL_HIGH                         0xf284
+#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS              0xf288
+#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS             0xf28c
+#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS          0xf290
+#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS         0xf294
+#define MPSC_1_ADDRESS_CONTROL_LOW                          0xf2a0
+#define MPSC_1_ADDRESS_CONTROL_HIGH                         0xf2a4
+#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS              0xf2a8
+#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS             0xf2ac
+#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS          0xf2b0
+#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS         0xf2b4
+#define MPSC_2_ADDRESS_CONTROL_LOW                          0xf2c0
+#define MPSC_2_ADDRESS_CONTROL_HIGH                         0xf2c4
+#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS              0xf2c8
+#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS             0xf2cc
+#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS          0xf2d0
+#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS         0xf2d4
+#define SERIAL_INIT_PCI_HIGH_ADDRESS                        0xf320
+#define SERIAL_INIT_LAST_DATA                               0xf324
+#define SERIAL_INIT_STATUS_AND_CONTROL                      0xf328
+#define COMM_UNIT_ARBITER_CONTROL                           0xf300
+#define COMM_UNIT_CROSS_BAR_TIMEOUT                         0xf304
+#define COMM_UNIT_INTERRUPT_CAUSE                           0xf310
+#define COMM_UNIT_INTERRUPT_MASK                            0xf314
+#define COMM_UNIT_ERROR_ADDRESS                             0xf314
+
+/****************************************/
+/* Cunit Debug  (for internal use)     */
+/****************************************/
+
+#define CUNIT_ADDRESS                                       0xf340
+#define CUNIT_COMMAND_AND_ID                                0xf344
+#define CUNIT_WRITE_DATA_LOW                                0xf348
+#define CUNIT_WRITE_DATA_HIGH                               0xf34c
+#define CUNIT_WRITE_BYTE_ENABLE                             0xf358
+#define CUNIT_READ_DATA_LOW                                 0xf350
+#define CUNIT_READ_DATA_HIGH                                0xf354
+#define CUNIT_READ_ID                                       0xf35c
+
+/****************************************/
+/* Fast Ethernet Unit Registers         */
+/****************************************/
+
+/* Ethernet */
+
+#define ETHERNET_PHY_ADDRESS_REGISTER                       0x2000
+#define ETHERNET_SMI_REGISTER                               0x2010
+
+/* Ethernet 0 */
+
+#define ETHERNET0_PORT_CONFIGURATION_REGISTER               0x2400
+#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER        0x2408
+#define ETHERNET0_PORT_COMMAND_REGISTER                     0x2410
+#define ETHERNET0_PORT_STATUS_REGISTER                      0x2418
+#define ETHERNET0_SERIAL_PARAMETRS_REGISTER                 0x2420
+#define ETHERNET0_HASH_TABLE_POINTER_REGISTER               0x2428
+#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW           0x2430
+#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH          0x2438
+#define ETHERNET0_SDMA_CONFIGURATION_REGISTER               0x2440
+#define ETHERNET0_SDMA_COMMAND_REGISTER                     0x2448
+#define ETHERNET0_INTERRUPT_CAUSE_REGISTER                  0x2450
+#define ETHERNET0_INTERRUPT_MASK_REGISTER                   0x2458
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0              0x2480
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1              0x2484
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2              0x2488
+#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3              0x248c
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0            0x24a0
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1            0x24a4
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2            0x24a8
+#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3            0x24ac
+#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0            0x24e0
+#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1            0x24e4
+#define ETHERNET0_MIB_COUNTER_BASE                          0x2500
+
+/* Ethernet 1 */
+
+#define ETHERNET1_PORT_CONFIGURATION_REGISTER               0x2800
+#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER        0x2808
+#define ETHERNET1_PORT_COMMAND_REGISTER                     0x2810
+#define ETHERNET1_PORT_STATUS_REGISTER                      0x2818
+#define ETHERNET1_SERIAL_PARAMETRS_REGISTER                 0x2820
+#define ETHERNET1_HASH_TABLE_POINTER_REGISTER               0x2828
+#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW           0x2830
+#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH          0x2838
+#define ETHERNET1_SDMA_CONFIGURATION_REGISTER               0x2840
+#define ETHERNET1_SDMA_COMMAND_REGISTER                     0x2848
+#define ETHERNET1_INTERRUPT_CAUSE_REGISTER                  0x2850
+#define ETHERNET1_INTERRUPT_MASK_REGISTER                   0x2858
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0              0x2880
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1              0x2884
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2              0x2888
+#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3              0x288c
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0            0x28a0
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1            0x28a4
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2            0x28a8
+#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3            0x28ac
+#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0            0x28e0
+#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1            0x28e4
+#define ETHERNET1_MIB_COUNTER_BASE                          0x2900
+
+/* Ethernet 2 */
+
+#define ETHERNET2_PORT_CONFIGURATION_REGISTER               0x2c00
+#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER        0x2c08
+#define ETHERNET2_PORT_COMMAND_REGISTER                     0x2c10
+#define ETHERNET2_PORT_STATUS_REGISTER                      0x2c18
+#define ETHERNET2_SERIAL_PARAMETRS_REGISTER                 0x2c20
+#define ETHERNET2_HASH_TABLE_POINTER_REGISTER               0x2c28
+#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW           0x2c30
+#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH          0x2c38
+#define ETHERNET2_SDMA_CONFIGURATION_REGISTER               0x2c40
+#define ETHERNET2_SDMA_COMMAND_REGISTER                     0x2c48
+#define ETHERNET2_INTERRUPT_CAUSE_REGISTER                  0x2c50
+#define ETHERNET2_INTERRUPT_MASK_REGISTER                   0x2c58
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0              0x2c80
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1              0x2c84
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2              0x2c88
+#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3              0x2c8c
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0            0x2ca0
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1            0x2ca4
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2            0x2ca8
+#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3            0x2cac
+#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0            0x2ce0
+#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1            0x2ce4
+#define ETHERNET2_MIB_COUNTER_BASE                          0x2d00
+
+/****************************************/
+/* SDMA Registers                       */
+/****************************************/
+
+#define SDMA_GROUP_CONFIGURATION_REGISTER                   0xb1f0
+#define CHANNEL0_CONFIGURATION_REGISTER                     0x4000
+#define CHANNEL0_COMMAND_REGISTER                           0x4008
+#define CHANNEL0_RX_CMD_STATUS                              0x4800
+#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES                 0x4804
+#define CHANNEL0_RX_BUFFER_POINTER                          0x4808
+#define CHANNEL0_RX_NEXT_POINTER                            0x480c
+#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER              0x4810
+#define CHANNEL0_TX_CMD_STATUS                              0x4C00
+#define CHANNEL0_TX_PACKET_SIZE                             0x4C04
+#define CHANNEL0_TX_BUFFER_POINTER                          0x4C08
+#define CHANNEL0_TX_NEXT_POINTER                            0x4C0c
+#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER              0x4c10
+#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER                0x4c14
+#define CHANNEL1_CONFIGURATION_REGISTER                     0x6000
+#define CHANNEL1_COMMAND_REGISTER                           0x6008
+#define CHANNEL1_RX_CMD_STATUS                              0x6800
+#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES                 0x6804
+#define CHANNEL1_RX_BUFFER_POINTER                          0x6808
+#define CHANNEL1_RX_NEXT_POINTER                            0x680c
+#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER              0x6810
+#define CHANNEL1_TX_CMD_STATUS                              0x6C00
+#define CHANNEL1_TX_PACKET_SIZE                             0x6C04
+#define CHANNEL1_TX_BUFFER_POINTER                          0x6C08
+#define CHANNEL1_TX_NEXT_POINTER                            0x6C0c
+#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER              0x6810
+#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER              0x6c10
+#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER                0x6c14
+
+/* SDMA Interrupt */
+
+#define SDMA_CAUSE                                          0xb820
+#define SDMA_MASK                                           0xb8a0
+
+
+/****************************************/
+/* Baude Rate Generators Registers      */
+/****************************************/
+
+/* BRG 0 */
+
+#define BRG0_CONFIGURATION_REGISTER                         0xb200
+#define BRG0_BAUDE_TUNING_REGISTER                          0xb204
+
+/* BRG 1 */
+
+#define BRG1_CONFIGURATION_REGISTER                         0xb208
+#define BRG1_BAUDE_TUNING_REGISTER                          0xb20c
+
+/* BRG 2 */
+
+#define BRG2_CONFIGURATION_REGISTER                         0xb210
+#define BRG2_BAUDE_TUNING_REGISTER                          0xb214
+
+/* BRG Interrupts */
+
+#define BRG_CAUSE_REGISTER                                  0xb834
+#define BRG_MASK_REGISTER                                   0xb8b4
+
+/* MISC */
+
+#define MAIN_ROUTING_REGISTER                               0xb400
+#define RECEIVE_CLOCK_ROUTING_REGISTER                      0xb404
+#define TRANSMIT_CLOCK_ROUTING_REGISTER                     0xb408
+#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER            0xb40c
+#define WATCHDOG_CONFIGURATION_REGISTER                     0xb410
+#define WATCHDOG_VALUE_REGISTER                             0xb414
+
+
+/****************************************/
+/* Flex TDM Registers                   */
+/****************************************/
+
+/* FTDM Port */
+
+#define FLEXTDM_TRANSMIT_READ_POINTER                       0xa800
+#define FLEXTDM_RECEIVE_READ_POINTER                        0xa804
+#define FLEXTDM_CONFIGURATION_REGISTER                      0xa808
+#define FLEXTDM_AUX_CHANNELA_TX_REGISTER                    0xa80c
+#define FLEXTDM_AUX_CHANNELA_RX_REGISTER                    0xa810
+#define FLEXTDM_AUX_CHANNELB_TX_REGISTER                    0xa814
+#define FLEXTDM_AUX_CHANNELB_RX_REGISTER                    0xa818
+
+/* FTDM Interrupts */
+
+#define FTDM_CAUSE_REGISTER                                 0xb830
+#define FTDM_MASK_REGISTER                                  0xb8b0
+
+
+/****************************************/
+/* GPP Interface Registers              */
+/****************************************/
+
+#define GPP_IO_CONTROL                                      0xf100
+#define GPP_LEVEL_CONTROL                                   0xf110
+#define GPP_VALUE                                           0xf104
+#define GPP_INTERRUPT_CAUSE                                 0xf108
+#define GPP_INTERRUPT_MASK                                  0xf10c
+
+#define MPP_CONTROL0                                        0xf000
+#define MPP_CONTROL1                                        0xf004
+#define MPP_CONTROL2                                        0xf008
+#define MPP_CONTROL3                                        0xf00c
+#define DEBUG_PORT_MULTIPLEX                                0xf014
+#define SERIAL_PORT_MULTIPLEX                               0xf010
+
+/****************************************/
+/* I2C Registers                        */
+/****************************************/
+
+#define I2C_SLAVE_ADDRESS                                   0xc000
+#define I2C_EXTENDED_SLAVE_ADDRESS                          0xc040
+#define I2C_DATA                                            0xc004
+#define I2C_CONTROL                                         0xc008
+#define I2C_STATUS_BAUDE_RATE                               0xc00C
+#define I2C_SOFT_RESET                                      0xc01c
+
+/****************************************/
+/* MPSC Registers                       */
+/****************************************/
+
+/* MPSC0  */
+
+#define MPSC0_MAIN_CONFIGURATION_LOW                        0x8000
+#define MPSC0_MAIN_CONFIGURATION_HIGH                       0x8004
+#define MPSC0_PROTOCOL_CONFIGURATION                        0x8008
+#define CHANNEL0_REGISTER1                                  0x800c
+#define CHANNEL0_REGISTER2                                  0x8010
+#define CHANNEL0_REGISTER3                                  0x8014
+#define CHANNEL0_REGISTER4                                  0x8018
+#define CHANNEL0_REGISTER5                                  0x801c
+#define CHANNEL0_REGISTER6                                  0x8020
+#define CHANNEL0_REGISTER7                                  0x8024
+#define CHANNEL0_REGISTER8                                  0x8028
+#define CHANNEL0_REGISTER9                                  0x802c
+#define CHANNEL0_REGISTER10                                 0x8030
+#define CHANNEL0_REGISTER11                                 0x8034
+
+/* MPSC1  */
+
+#define MPSC1_MAIN_CONFIGURATION_LOW                        0x9000
+#define MPSC1_MAIN_CONFIGURATION_HIGH                       0x9004
+#define MPSC1_PROTOCOL_CONFIGURATION                        0x9008
+#define CHANNEL1_REGISTER1                                  0x900c
+#define CHANNEL1_REGISTER2                                  0x9010
+#define CHANNEL1_REGISTER3                                  0x9014
+#define CHANNEL1_REGISTER4                                  0x9018
+#define CHANNEL1_REGISTER5                                  0x901c
+#define CHANNEL1_REGISTER6                                  0x9020
+#define CHANNEL1_REGISTER7                                  0x9024
+#define CHANNEL1_REGISTER8                                  0x9028
+#define CHANNEL1_REGISTER9                                  0x902c
+#define CHANNEL1_REGISTER10                                 0x9030
+#define CHANNEL1_REGISTER11                                 0x9034
+
+/* MPSCs Interupts  */
+
+#define MPSC0_CAUSE                                         0xb804
+#define MPSC0_MASK                                          0xb884
+#define MPSC1_CAUSE                                         0xb80c
+#define MPSC1_MASK                                          0xb88c
+
+#endif /* __INCgt64240rh */
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/gt64240_dep.h linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/gt64240_dep.h
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/gt64240_dep.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/gt64240_dep.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,57 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/gt64240/gt64240-dep.h
+ *     Board-dependent definitions for GT-64120 chip.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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_GT64240_DEP_H
+#define _ASM_GT64240_DEP_H
+
+#include <asm/addrspace.h>		/* for KSEG1ADDR() */
+#include <asm/byteorder.h>		/* for cpu_to_le32() */
+
+/*
+ * PCI address allocation
+ */
+#if 0
+#define GT_PCI_MEM_BASE    (0x22000000)
+#define GT_PCI_MEM_SIZE    GT_DEF_PCI0_MEM0_SIZE
+#define GT_PCI_IO_BASE     (0x20000000)
+#define GT_PCI_IO_SIZE     GT_DEF_PCI0_IO_SIZE
+#endif
+
+extern unsigned long gt64240_base;
+
+#define GT64240_BASE       (gt64240_base)
+
+/*
+ * 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 *)(GT64240_BASE+(ofs)) = cpu_to_le32(data)
+#define GT_READ(ofs, data)   \
+        *(data) = le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs)))
+#define GT_READ_DATA(ofs)    \
+        le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs)))
+
+#define GT_WRITE_16(ofs, data)  \
+        *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data)
+#define GT_READ_16(ofs, data)   \
+        *(data) = le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs)))
+
+#define GT_WRITE_8(ofs, data)  \
+        *(volatile u8 *)(GT64240_BASE+(ofs)) = data
+#define GT_READ_8(ofs, data)   \
+        *(data) = *(volatile u8 *)(GT64240_BASE+(ofs))
+
+#endif  /* _ASM_GT64120_MOMENCO_OCELOT_GT64120_DEP_H */
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/int-handler.S linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/int-handler.S
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/int-handler.S	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * First-level interrupt dispatcher for ocelot board.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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 __ASSEMBLY__
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.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(ocelot_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_IP2	/* int0 hardware line */
+		bnez	t1, ll_pri_enet_irq
+		 andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_sec_enet_irq
+		 andi	t1, t0, STATUSF_IP4	/* int2 hardware line */
+		bnez	t1, ll_uart_irq
+		 andi	t1, t0, STATUSF_IP5	/* int3 hardware line */
+		bnez	t1, ll_cpci_irq
+		 andi	t1, t0, STATUSF_IP6	/* int4 hardware line */
+		bnez	t1, ll_galileo_p0_irq
+		 andi	t1, t0, STATUSF_IP7	/* cpu timer */
+		bnez	t1, ll_cputimer_irq
+
+                /* now look at the extended interrupts */
+		mfc0	t0, CP0_CAUSE
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		/* shift the mask 8 bits left to line up the bits */
+		 sll	t2, t1, 8
+
+		 and	t0, t2
+		 srl	t0, t0, 16
+
+		 andi	t1, t0, STATUSF_IP8	/* int6 hardware line */
+		bnez	t1, ll_galileo_p1_irq
+		 andi	t1, t0, STATUSF_IP9	/* int7 hardware line */
+		bnez	t1, ll_pmc_irq
+		 andi	t1, t0, STATUSF_IP10	/* int8 hardware line */
+		bnez	t1, ll_cpci_abcd_irq
+		 andi	t1, t0, STATUSF_IP11	/* int9 hardware line */
+		bnez	t1, ll_testpoint_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(ocelot_handle_int)
+
+		.align	5
+ll_pri_enet_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_sec_enet_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_uart_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_p0_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cputimer_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_galileo_p1_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pmc_irq:
+		li	a0, 9
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_cpci_abcd_irq:
+		li	a0, 10
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_testpoint_irq:
+		li	a0, 11
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/irq.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/irq.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/irq.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.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.
+ *
+ *  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>
+
+
+static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED;
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in)
+{
+	unsigned long status;
+	unsigned clr_mask;
+	unsigned set_mask;
+
+	/* do the low 8 bits first */
+	clr_mask = 0xff & clr_mask_in;
+	set_mask = 0xff & set_mask_in;
+	status = read_32bit_cp0_register(CP0_STATUS);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	write_32bit_cp0_register(CP0_STATUS, status);
+
+	/* do the high 8 bits */
+	clr_mask = 0xff & (clr_mask_in >> 8);
+	set_mask = 0xff & (set_mask_in >> 8);
+	status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL);
+	status &= ~((clr_mask & 0xFF) << 8);
+	status |= (set_mask & 0xFF) << 8;
+	write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status);
+}
+
+static inline void mask_irq(unsigned int irq)
+{
+	modify_cp0_intmask(irq, 0);
+}
+
+static inline void unmask_irq(unsigned int irq)
+{
+	modify_cp0_intmask(0, irq);
+}
+
+static void enable_cp7000_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rm7000_irq_lock, flags);
+	unmask_irq(1 << irq);
+	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
+}
+
+static unsigned int startup_cp7000_irq(unsigned int irq)
+{
+	enable_cp7000_irq(irq);
+
+	return 0;				/* never anything pending */
+}
+
+static void disable_cp7000_irq(unsigned int irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&rm7000_irq_lock, flags);
+	mask_irq(1 << irq);
+	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
+}
+
+#define shutdown_cp7000_irq disable_cp7000_irq
+
+static void mask_and_ack_cp7000_irq(unsigned int irq)
+{
+	mask_irq(1 << irq);
+}
+
+static void end_cp7000_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_irq(1 << irq);
+}
+
+static struct hw_interrupt_type cp7000_hpcdma_irq_type = {
+	"CP7000",
+	startup_cp7000_irq,
+	shutdown_cp7000_irq,
+	enable_cp7000_irq,
+	disable_cp7000_irq,
+	mask_and_ack_cp7000_irq,
+	end_cp7000_irq,
+	NULL
+};
+
+
+extern asmlinkage void ocelot_handle_int(void);
+extern void gt64240_irq_init(void);
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	/*
+	 * 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);
+	__cli();
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, ocelot_handle_int);
+	init_generic_irq();
+
+	for (i = 0; i <= 15; i++) {
+		irq_desc[i].status	= IRQ_DISABLED;
+		irq_desc[i].action	= 0;
+		irq_desc[i].depth	= 1;
+		irq_desc[i].handler	= &cp7000_hpcdma_irq_type;
+	}
+
+	gt64240_irq_init();
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("start kgdb ...\n");
+	set_debug_traps();
+	breakpoint();	/* you may move this line to whereever you want :-) */
+#endif
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
+}
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/ocelot_pld.h linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/ocelot_pld.h
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/ocelot_pld.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/ocelot_pld.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,34 @@
+/*
+ * Ocelot Board Register Definitions
+ *
+ * (C) 2001 Red Hat, Inc.
+ *
+ * GPL'd
+ */
+#ifndef __MOMENCO_OCELOT_PLD_H__
+#define __MOMENCO_OCELOT_PLD_H__
+
+#if 0
+#define OCELOT_CS0_ADDR (0xe0020000)
+#else
+#define OCELOT_CS0_ADDR (0xfc000000)
+#endif
+
+#define OCELOT_REG_BOARDREV (0)
+#define OCELOT_REG_PLD1_ID (1)
+#define OCELOT_REG_PLD2_ID (2)
+#define OCELOT_REG_RESET_STATUS (3)
+#define OCELOT_REG_BOARD_STATUS (4)
+#define OCELOT_REG_CPCI_ID (5)
+#define OCELOT_REG_I2C_CTRL (8)
+#define OCELOT_REG_EEPROM_MODE (9)
+#define OCELOT_REG_INTMASK (10)
+#define OCELOT_REG_INTSTATUS (11)
+#define OCELOT_REG_INTSET (12)
+#define OCELOT_REG_INTCLR (13)
+
+#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
+#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
+
+
+#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/pci-irq.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/pci-irq.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/pci-irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/pci-irq.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on work for the Linux port to the Ocelot board, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * arch/mips/momentum/ocelot_g/pci.c
+ *     Board-specific PCI routines for gt64240 controller.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+
+void __init gt64240_board_pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
+	u16 cmd;
+
+	/* loop over all known devices on this bus */
+	list_for_each(devices_link, &(current_bus->devices)) {
+
+		devices = pci_dev_b(devices_link);
+		if (devices == NULL)
+			continue;
+
+		if ((current_bus->number == 0) &&
+				PCI_SLOT(devices->devfn) == 1) {
+			/* Intel 82543 Gigabit MAC */
+			devices->irq = 2;       /* irq_nr is 2 for INT0 */
+		} else if ((current_bus->number == 0) &&
+				PCI_SLOT(devices->devfn) == 2) {
+			/* Intel 82543 Gigabit MAC */
+			devices->irq = 3;       /* irq_nr is 3 for INT1 */
+		} else if ((current_bus->number == 1) &&
+				PCI_SLOT(devices->devfn) == 3) {
+			/* Intel 21555 bridge */
+			devices->irq = 5;       /* irq_nr is 8 for INT6 */
+		} else if ((current_bus->number == 1) &&
+				PCI_SLOT(devices->devfn) == 4) {
+			/* PMC Slot */
+			devices->irq = 9;       /* irq_nr is 9 for INT7 */
+		} else {
+			/* We don't have assign interrupts for other devices. */
+			devices->irq = 0xff;
+		}
+
+		/* Assign an interrupt number for the device */
+		bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq);
+
+		/* enable master for everything but the GT-64240 */
+		if (((current_bus->number != 0) && (current_bus->number != 1))
+				|| (PCI_SLOT(devices->devfn) != 0)) {
+			bus->ops->read_word(devices, PCI_COMMAND, &cmd);
+			cmd |= PCI_COMMAND_MASTER;
+			bus->ops->write_word(devices, PCI_COMMAND, cmd);
+		}
+	}
+}
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/pci.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/pci.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/pci.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/pci.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,568 @@
+/*
+ * Copyright 2002 Momentum Computer
+ * Author: Matthew Dharm <mdharm@momenco.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 "gt64240.h"
+
+#include <linux/init.h>
+
+#ifdef CONFIG_PCI
+
+#define SELF 0
+#define MASTER_ABORT_BIT 0x100
+
+/*
+ * These functions and structures provide the BIOS scan and mapping of the PCI
+ * devices.
+ */
+
+#define MAX_PCI_DEVS 10
+
+void gt64240_board_pcibios_fixup_bus(struct pci_bus* c);
+
+/*  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.
+ */
+
+
+/*
+ * 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)
+{
+	/* Accessing device 31 crashes the GT-64240. */
+	if (dev < 5)
+		return 0;
+	return -1;
+}
+
+/*
+ * galileo_pcibios_(read/write)_config_(dword/word/byte) -
+ *
+ * reads/write a dword/word/byte register from the configuration space
+ * of a device.
+ *
+ * Note that bus 0 and bus 1 are local, and we assume all other busses are
+ * bridged from bus 1.  This is a safe assumption, since any other
+ * configuration will require major modifications to the CP7000G
+ *
+ * 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, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT);
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT);
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* read the data */
+	GT_READ(data_reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_read_config_word(struct pci_dev *device,
+					     int offset, u16* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT);
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT);
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* read the data */
+	GT_READ_16(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_byte(struct pci_dev *device,
+					     int offset, u8* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_READ_8(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_dword(struct pci_dev *device,
+					      int offset, u32 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_WRITE(data_reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_write_config_word(struct pci_dev *device,
+					     int offset, u16 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_WRITE_16(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_byte(struct pci_dev *device,
+					     int offset, u8 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	/* verify the range */
+	if (pci_range_ck(bus, dev))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* select the GT-64240 registers to communicate with the PCI bus */
+	if (bus == 0) {
+		address_reg = PCI_0CONFIGURATION_ADDRESS;
+		data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER;
+	} else {
+		address_reg = PCI_1CONFIGURATION_ADDRESS;
+		data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER;
+		if (bus == 1)
+			bus = 0;
+	}
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	GT_WRITE(address_reg, address);
+
+	/* write the data */
+	GT_WRITE_8(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void galileo_pcibios_set_master(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER;
+	galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+}
+
+/*  Externally-expected functions.  Do not change function names  */
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	u8 tmp1;
+	int idx;
+	struct resource *r;
+
+	galileo_pcibios_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) {
+		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) {
+		printk(KERN_WARNING "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) {
+		printk(KERN_WARNING "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)
+{
+	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;
+
+	return;
+
+#if 0
+	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);
+	}
+#endif
+}
+
+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;
+	}
+}
+
+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
+};
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+	gt64240_board_pcibios_fixup_bus(c);
+}
+
+
+/********************************************************************
+* pci0P2PConfig - This function set the PCI_0 P2P configurate.
+*                 For more information on the P2P read PCI spec.
+*
+* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
+*                                      Boundry.
+*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
+*                                      Boundry.
+*          unsigned int busNum - The CPI bus number to which the PCI interface
+*                                      is connected.
+*          unsigned int devNum - The PCI interface's device number.
+*
+* Returns:  true.
+*/
+void pci0P2PConfig(unsigned int SecondBusLow,unsigned int SecondBusHigh,
+                   unsigned int busNum,unsigned int devNum)
+{
+	uint32_t regData;
+
+	regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
+			((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
+	GT_WRITE(PCI_0P2P_CONFIGURATION, regData);
+}
+
+/********************************************************************
+* pci1P2PConfig - This function set the PCI_1 P2P configurate.
+*                 For more information on the P2P read PCI spec.
+*
+* Inputs:  unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
+*               Boundry.
+*          unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
+*               Boundry.
+*          unsigned int busNum - The CPI bus number to which the PCI interface
+*               is connected.
+*          unsigned int devNum - The PCI interface's device number.
+*
+* Returns:  true.
+*/
+void pci1P2PConfig(unsigned int SecondBusLow,unsigned int SecondBusHigh,
+                   unsigned int busNum,unsigned int devNum)
+{
+	uint32_t regData;
+
+	regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
+			((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
+	GT_WRITE(PCI_1P2P_CONFIGURATION, regData);
+}
+
+#define PCI0_STATUS_COMMAND_REG                 0x4
+#define PCI1_STATUS_COMMAND_REG                 0x84
+
+void __init pcibios_init(void)
+{
+	/* Reset PCI I/O and PCI MEM values */
+	ioport_resource.start = 0xe0000000;
+	ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
+	iomem_resource.start  = 0xc0000000;
+	iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
+
+	pci_scan_bus(0, &galileo_pci_ops, NULL);
+	pci_scan_bus(1, &galileo_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+        printk(KERN_INFO "rr: pcibios_setup\n");
+        /* Nothing to do for now.  */
+
+        return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+#endif	/* CONFIG_PCI */
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/prom.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/prom.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/prom.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/prom.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2002 Momentum Computer Inc.
+ * Author: Matthew Dharm <mdharm@momenco.com>
+ *
+ * Based on Ocelot Linux port, which is
+ * Copyright 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>
+#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 "gt64240.h"
+#include "ocelot_pld.h"
+
+struct callvectors {
+	int	(*open) (char*, int, int);
+	int	(*close) (int);
+	int	(*read) (int, void*, int);
+	int	(*write) (int, void*, int);
+	off_t	(*lseek) (int, off_t, int);
+	int	(*printf) (const char*, ...);
+	void	(*cacheflush) (void);
+	char*	(*gets) (char*);
+};
+
+struct callvectors* debug_vectors;
+char arcs_cmdline[CL_SIZE];
+
+extern unsigned long gt64240_base;
+extern unsigned long bus_clock;
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+extern unsigned char prom_mac_addr_base[6];
+#endif
+
+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, char **arg, char** env, struct callvectors *cv)
+{
+	int i;
+	uint32_t tmp;
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* 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_MOMENCO;
+	mips_machtype = MACH_MOMENCO_OCELOT_G;
+
+#ifdef CONFIG_GALILLEO_GT64240_ETH
+	/* get the base MAC address for on-board ethernet ports */
+	memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
+#endif
+
+	while (*env) {
+		if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
+			gt64240_base = simple_strtol(*env + strlen("gtbase="),
+							NULL, 16);
+		}
+		if (strncmp("busclock", *env, strlen("busclock")) == 0) {
+			bus_clock = simple_strtol(*env + strlen("busclock="),
+							NULL, 10);
+		}
+		*env++;
+	}
+
+	debug_vectors->printf("Booting Linux kernel...\n");
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/reset.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/reset.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/reset.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/reset.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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>
+#include <linux/delay.h>
+
+void momenco_ocelot_restart(char *command)
+{
+	void *nvram = ioremap_nocache(0x2c807000, 0x1000);
+
+	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)
+{
+	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 momenco_ocelot_power_off(void)
+{
+	momenco_ocelot_halt();
+}
diff -urN linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/setup.c linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/setup.c
--- linux-2.4.20-pre6/arch/mips/momentum/ocelot_g/setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,258 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Momentum Computer Ocelot-G (CP7000G) - 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: Matthew Dharm, Momentum Computer
+ *   mdharm@momenco.com
+ *
+ * Author: RidgeRun, Inc.
+ *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 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.
+ *
+ *  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.h>
+#include <linux/types.h>
+#include <linux/mc146818rtc.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 <linux/vmalloc.h>
+#include <asm/time.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 <linux/version.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+#include "gt64240.h"
+#include "ocelot_pld.h"
+
+extern struct rtc_ops no_rtc_ops;
+
+unsigned long gt64240_base;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void momenco_ocelot_restart(char *command);
+extern void momenco_ocelot_halt(void);
+extern void momenco_ocelot_power_off(void);
+
+extern void gt64240_time_init(void);
+extern void momenco_ocelot_irq_setup(void);
+
+static char reset_reason;
+
+#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1)
+
+static void __init setup_l3cache(unsigned long size);
+
+void __init bus_error_init(void) { /* nothing */ }
+
+/* setup code for a handoff from a version 2 PMON 2000 PROM */
+void PMON_v2_setup(void)
+{
+	/* A wired TLB entry for the GT64240 and the serial port. The
+	   GT64240 is going to be hit on every IRQ anyway - there's
+	   absolutely no point in letting it be a random TLB entry, as
+	   it'll just cause needless churning of the TLB. And we use
+	   the other half for the serial port, which is just a PITA
+	   otherwise :)
+
+		Device			Physical	Virtual
+		GT64240 Internal Regs	0xf4000000	0xe0000000
+		UARTs (CS2)		0xfd000000	0xe0001000
+	*/
+	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K);
+	add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), 0xfd000000, PM_4K);
+
+	/* 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
+	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
+
+		Ocelot PLD (CS0)	0xfc000000	0xe0020000
+		NVRAM (CS1)		0xfc800000	0xe0030000
+	*/
+	add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), 0xfc000000, PM_64K);
+	add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), 0xfc800000, PM_64K);
+
+	gt64240_base = 0xf4000000;
+}
+
+void __init momenco_ocelot_g_setup(void)
+{
+	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
+	unsigned int tmpword;
+
+	board_time_init = gt64240_time_init;
+
+	_machine_restart = momenco_ocelot_restart;
+	_machine_halt = momenco_ocelot_halt;
+	_machine_power_off = momenco_ocelot_power_off;
+
+	/*
+	 * initrd_start = (ulong)ocelot_initrd_start;
+	 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
+	 * initrd_below_start_ok = 1;
+	 */
+	rtc_ops = &no_rtc_ops;
+
+	/* do handoff reconfiguration */
+	PMON_v2_setup();
+
+	/* Turn off the Bit-Error LED */
+	OCELOT_PLD_WRITE(0x80, INTCLR);
+
+	tmpword = OCELOT_PLD_READ(BOARDREV);
+	if (tmpword < 26)
+		printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword);
+	else
+		printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword);
+
+	tmpword = OCELOT_PLD_READ(PLD1_ID);
+	printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(PLD2_ID);
+	printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
+	tmpword = OCELOT_PLD_READ(RESET_STATUS);
+	printk("Reset reason: 0x%x\n", tmpword);
+	reset_reason = tmpword;
+	OCELOT_PLD_WRITE(0xff, RESET_STATUS);
+
+	tmpword = OCELOT_PLD_READ(BOARD_STATUS);
+	printk("Board Status register: 0x%02x\n", tmpword);
+	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
+	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
+	printk("  - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
+	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
+	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
+
+	if (tmpword&12)
+		l3func((1<<(((tmpword&12) >> 2)+20)));
+
+	switch(tmpword &3) {
+	case 3:
+		/* 512MiB -- two banks of 256MiB */
+		add_memory_region(  0x0<<20, 0x100<<20, BOOT_MEM_RAM);
+/*
+		add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
+*/
+		break;
+	case 2:
+		/* 256MiB -- two banks of 128MiB */
+		add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM);
+		add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
+		break;
+	case 1:
+		/* 128MiB -- 64MiB per bank */
+		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
+		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	case 0:
+		/* 64MiB */
+		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
+		break;
+	}
+
+	/* FIXME: Fix up the DiskOnChip mapping */
+	GT_WRITE(0x468, 0xfef73);
+}
+
+extern int rm7k_tcache_enabled;
+/*
+ * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
+ */
+#define Page_Invalidate_T 0x16
+static void __init setup_l3cache(unsigned long size)
+{
+	int register i;
+	unsigned long tmp;
+
+	printk("Enabling L3 cache...");
+
+	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
+	GT_READ(0, &tmp);
+	GT_WRITE(0, tmp | (1<<14));
+
+	/* Enable the L3 cache in the CPU */
+	set_cp0_config(1<<12 /* CONF_TE */);
+
+	/* Clear the cache */
+	set_taglo(0);
+	set_taghi(0);
+
+	for (i=0; i < size; i+= 4096) {
+		__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" (Page_Invalidate_T));
+	}
+
+	/* Let the RM7000 MM code know that the tertiary cache is enabled */
+	rm7k_tcache_enabled = 1;
+
+	printk("Done\n");
+}
+
+
+/* This needs to be one of the first initcalls, because no I/O port access
+   can work before this */
+
+static int io_base_ioremap(void)
+{
+	/* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
+	void *io_remap_range = ioremap(0xc0000000, 0x30000000);
+
+	if (!io_remap_range) {
+		panic("Could not ioremap I/O port range");
+	}
+	printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range);
+	set_io_port_base(io_remap_range - 0xc0000000);
+
+	return 0;
+}
+
+module_init(io_base_ioremap);
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/Makefile linux-2.4.20-pre7/arch/mips/sgi-ip22/Makefile
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/Makefile	Thu Sep 12 20:01:40 2002
@@ -18,6 +18,7 @@
          ip22-gio.o ip22-rtc.o ip22-reset.o ip22-system.o ip22-setup.o
 
 obj-$(CONFIG_BOARD_SCACHE)	+= ip22-sc.o
+obj-$(CONFIG_IP22_EISA)		+= ip22-eisa.o
 
 ip22-irq.o: ip22-irq.S
 
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-berr.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-berr.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-berr.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-berr.c	Thu Sep 12 20:01:40 2002
@@ -24,7 +24,7 @@
 
 static void save_and_clear_buserr(void)
 {
-	/* save memory controler's error status registers */ 
+	/* 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;
@@ -34,8 +34,8 @@
 }
 
 /*
- * 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 
+ * 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.
  */
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-eisa.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-eisa.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-eisa.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-eisa.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,300 @@
+/*
+ * Basic EISA bus support for the SGI Indigo-2.
+ *
+ * (C) 2002 Pascal Dameme <netinet@freesurf.fr>
+ *      and Marc Zyngier <mzyngier@freesurf.fr>
+ *
+ * This code is released under both the GPL version 2 and BSD
+ * licenses.  Either license may be used.
+ *
+ * This code offers a very basic support for this EISA bus present in
+ * the SGI Indigo-2. It currently only supports PIO (forget about DMA
+ * for the time being). This is enough for a low-end ethernet card,
+ * but forget about your favorite SCSI card...
+ *
+ * TODO :
+ * - Fix bugs...
+ * - Add ISA support
+ * - Add DMA (yeah, right...).
+ * - Fix more bugs.
+ */
+
+#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/delay.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/sgi/sgint23.h>
+
+extern int EISA_bus;
+extern void do_IRQ(int irq, struct pt_regs *regs);
+
+#define EISA_MAX_SLOTS		  4
+#define EISA_MAX_IRQ             16
+
+#define EISA_TO_PHYS(x)  (0x00080000 | (x))
+#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
+
+#define EIU_MODE_REG     0x0009ffc0
+#define EIU_STAT_REG     0x0009ffc4
+#define EIU_PREMPT_REG   0x0009ffc8
+#define EIU_QUIET_REG    0x0009ffcc
+#define EIU_INTRPT_ACK   0x00090004
+
+#define EISA_DMA1_STATUS            8
+#define EISA_INT1_CTRL           0x20
+#define EISA_INT1_MASK           0x21
+#define EISA_INT2_CTRL           0xA0
+#define EISA_INT2_MASK           0xA1
+#define EISA_DMA2_STATUS         0xD0
+#define EISA_DMA2_WRITE_SINGLE   0xD4
+#define EISA_EXT_NMI_RESET_CTRL 0x461
+#define EISA_INT1_EDGE_LEVEL    0x4D0
+#define EISA_INT2_EDGE_LEVEL    0x4D1
+#define EISA_VENDOR_ID_OFFSET   0xC80
+
+#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
+#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
+#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
+#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
+
+static char *decode_eisa_sig(u8 * sig)
+{
+	static char sig_str[8];
+	u16 rev;
+
+	if (sig[0] & 0x80)
+		return NULL;
+
+	sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+	sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+	sig_str[2] = (sig[1] & 0x1f) + ('A' - 1);
+	rev = (sig[2] << 8) | sig[3];
+	sprintf(sig_str + 3, "%04X", rev);
+
+	return sig_str;
+}
+
+static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u8 eisa_irq;
+	u8 dma1, dma2;
+
+	eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
+	dma1 = EISA_READ_8(EISA_DMA1_STATUS);
+	dma2 = EISA_READ_8(EISA_DMA2_STATUS);
+
+	if (eisa_irq >= EISA_MAX_IRQ) {
+		/* Oops, Bad Stuff Happened... */
+		printk("eisa_irq %d out of bound\n", eisa_irq);
+
+		EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+		EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+	} else
+		do_IRQ(eisa_irq, regs);
+}
+
+static void enable_eisa1_irq(unsigned int irq)
+{
+	unsigned long flags;
+	u8 mask;
+
+	save_and_cli(flags);
+
+	mask = EISA_READ_8(EISA_INT1_MASK);
+	mask &= ~((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_MASK, mask);
+
+	restore_flags(flags);
+}
+
+static unsigned int startup_eisa1_irq(unsigned int irq)
+{
+	u8 edge;
+
+	/* Only use edge interrupts for EISA */
+
+	edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
+	edge &= ~((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
+
+	enable_eisa1_irq(irq);
+	return 0;
+}
+
+static void disable_eisa1_irq(unsigned int irq)
+{
+	u8 mask;
+
+	mask = EISA_READ_8(EISA_INT1_MASK);
+	mask |= ((u8) (1 << irq));
+	EISA_WRITE_8(EISA_INT1_MASK, mask);
+}
+
+#define shutdown_eisa1_irq	disable_eisa1_irq
+
+static void mask_and_ack_eisa1_irq(unsigned int irq)
+{
+	disable_eisa1_irq(irq);
+
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+}
+
+static void end_eisa1_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_eisa1_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_eisa1_irq_type = {
+	"IP22 EISA",
+	startup_eisa1_irq,
+	shutdown_eisa1_irq,
+	enable_eisa1_irq,
+	disable_eisa1_irq,
+	mask_and_ack_eisa1_irq,
+	end_eisa1_irq,
+	NULL
+};
+
+static void enable_eisa2_irq(unsigned int irq)
+{
+	unsigned long flags;
+	u8 mask;
+
+	save_and_cli(flags);
+
+	mask = EISA_READ_8(EISA_INT2_MASK);
+	mask &= ~((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_MASK, mask);
+
+	restore_flags(flags);
+}
+
+static unsigned int startup_eisa2_irq(unsigned int irq)
+{
+	u8 edge;
+
+	/* Only use edge interrupts for EISA */
+
+	edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
+	edge &= ~((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
+
+	enable_eisa2_irq(irq);
+	return 0;
+}
+
+static void disable_eisa2_irq(unsigned int irq)
+{
+	u8 mask;
+
+	mask = EISA_READ_8(EISA_INT2_MASK);
+	mask |= ((u8) (1 << (irq - 8)));
+	EISA_WRITE_8(EISA_INT2_MASK, mask);
+}
+
+#define shutdown_eisa2_irq	disable_eisa2_irq
+
+static void mask_and_ack_eisa2_irq(unsigned int irq)
+{
+	disable_eisa2_irq(irq);
+
+	EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+}
+
+static void end_eisa2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_eisa2_irq(irq);
+}
+
+static struct hw_interrupt_type ip22_eisa2_irq_type = {
+	"IP22 EISA",
+	startup_eisa2_irq,
+	shutdown_eisa2_irq,
+	enable_eisa2_irq,
+	disable_eisa2_irq,
+	mask_and_ack_eisa2_irq,
+	end_eisa2_irq,
+	NULL
+};
+
+static struct irqaction eisa_action = {
+	ip22_eisa_intr, 0, 0, "EISA", NULL, NULL
+};
+
+static struct irqaction cascade_action = {
+	no_action, 0, 0, "EISA cascade", NULL, NULL
+};
+
+int __init ip22_eisa_init(void)
+{
+	int i, c;
+	char *str;
+	u8 *slot_addr;
+
+	printk("EISA: Probing bus...\n");
+	for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
+		slot_addr =
+		    (u8 *) EISA_TO_KSEG1((0x1000 * i) +
+					 EISA_VENDOR_ID_OFFSET);
+		if ((str = decode_eisa_sig(slot_addr))) {
+			printk("EISA: slot %d : %s detected.\n", i, str);
+			c++;
+		}
+	}
+	printk("EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
+#ifdef CONFIG_ISA
+	printk("ISA support compiled in.\n");
+#endif
+
+	/* Warning : BlackMagicAhead(tm).
+	   Please wave your favorite dead chicken over the busses */
+
+	/* First say hello to the EIU */
+	EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
+	EIU_WRITE_32(EIU_QUIET_REG, 1);
+	EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
+
+	/* Now be nice to the EISA chipset */
+	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
+	for (i = 0; i < 10000; i++);	/* Wait long enough for the dust to settle */
+	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
+	EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
+	EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
+	EISA_WRITE_8(EISA_INT1_MASK, 0);
+	EISA_WRITE_8(EISA_INT2_MASK, 8);
+	EISA_WRITE_8(EISA_INT1_MASK, 4);
+	EISA_WRITE_8(EISA_INT2_MASK, 2);
+	EISA_WRITE_8(EISA_INT1_MASK, 1);
+	EISA_WRITE_8(EISA_INT2_MASK, 1);
+	EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
+	EISA_WRITE_8(EISA_INT2_MASK, 0xff);
+	EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
+
+	for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 1;
+		if (i < (SGINT_EISA + 8))
+			irq_desc[i].handler = &ip22_eisa1_irq_type;
+		else
+			irq_desc[i].handler = &ip22_eisa2_irq_type;
+	}
+
+	/* Cannot use request_irq because of kmalloc not being ready at such
+	 * an early stage. Yes, I've been bitten... */
+	setup_irq(SGI_EISA_IRQ, &eisa_action);
+	setup_irq(SGINT_EISA + 2, &cascade_action);
+
+	EISA_bus = 1;
+	return 0;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-gio.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-gio.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-gio.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-gio.c	Thu Sep 12 20:01:40 2002
@@ -1,6 +1,6 @@
-/* 
+/*
  * ip22-gio.c: Support for GIO64 bus (inspired by PCI code)
- * 
+ *
  * Copyright (C) 2002 Ladislav Michl
  */
 
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 
+#include <asm/addrspace.h>
 #include <asm/sgi/sgimc.h>
 #include <asm/sgi/sgigio.h>
 
@@ -67,7 +68,7 @@
 {
 	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)
@@ -77,7 +78,7 @@
 		p += sprintf(p, "    BaseAddr 0x%08lx, MapSize 0x%08x\n",
 			     gio_slot[i].base_addr, gio_slot[i].map_size);
 	}
-	
+
 	return p - buf;
 }
 
@@ -92,7 +93,7 @@
  * @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. 
+ * 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.
@@ -101,12 +102,12 @@
 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) && 
+		if (!(gio_slot[i].flags & GIO_NO_DEVICE) &&
 		   (device == GIO_ANY_ID || device == gio_slot[i].device))
 			return &gio_slot[i];
-	
+
 	return NULL;
 }
 
@@ -119,7 +120,7 @@
 
 extern int ip22_baddr(unsigned int *val, unsigned long addr);
 
-/** 
+/**
  * sgigio_init - scan the GIO space and figure out what hardware is actually
  * present.
  */
@@ -146,7 +147,7 @@
 		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 -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-int.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-int.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-int.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-int.c	Thu Sep 12 20:01:40 2002
@@ -4,7 +4,7 @@
  *
  * 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) 
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
  *                    - Indigo2 changes
  *                    - Interrupt handling fixes
  * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
@@ -20,7 +20,6 @@
 
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
-#include <asm/gdb-stub.h>
 
 #include <asm/sgi/sgint23.h>
 #include <asm/sgi/sgihpc.h>
@@ -41,6 +40,7 @@
 
 extern asmlinkage void indyIRQ(void);
 extern void do_IRQ(int irq, struct pt_regs *regs);
+extern int ip22_eisa_init (void);
 
 static void enable_local0_irq(unsigned int irq)
 {
@@ -187,7 +187,7 @@
 {
 #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));
@@ -276,7 +276,7 @@
 	/* if irq == 0, then the interrupt has already been cleared */
 	if (irq)
 		do_IRQ(irq, regs);
-	return;	
+	return;
 }
 
 extern void be_ip22_interrupt(int irq, struct pt_regs *regs);
@@ -292,11 +292,11 @@
 	irq_exit(cpu, irq);
 }
 
-static struct irqaction local0_cascade = 
+static struct irqaction local0_cascade =
 	{ no_action, SA_INTERRUPT, 0, "local0 cascade", NULL, NULL };
-static struct irqaction local1_cascade = 
+static struct irqaction local1_cascade =
 	{ no_action, SA_INTERRUPT, 0, "local1 cascade", NULL, NULL };
-static struct irqaction buserr = 
+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 };
@@ -409,10 +409,14 @@
 	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
+#ifdef CONFIG_IP22_EISA
+	if (!sgi_guiness)	/* Only Indigo-2 have EISA stuff */
+	        ip22_eisa_init ();
+#endif
 }
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-irq.S linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-irq.S
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-irq.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-irq.S	Thu Sep 12 20:01:40 2002
@@ -65,10 +65,8 @@
 	 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
-
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
 	 nop				# delay slot
 
@@ -88,38 +86,33 @@
 	 andi	a0, s0, CAUSEF_IP6	# delay slot, check bus error
 
 	/* Wheee, local level one interrupt. */
-	move	a0, sp
 	jal	indy_local1_irqdispatch
-	 nop
-
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
-	 nop
+	 nop				# delay slot
 
 1:
 	beq	a0, zero, 1f
-	 nop
+	 andi	a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)	# delay slot
 
 	/* Wheee, an asynchronous bus error... */
-	move	a0, sp
 	jal	indy_buserror_irq
-	 nop
-
+	 move	a0, sp			# delay slot
 	j	ret_from_irq
-	 nop
+	 nop				# delay slot
 
 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 
+	 * 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
+	 nop			  	# delay slot
 
 	/* Must be one of the 8254 timers... */
-	move	a0, sp
 	jal	indy_8254timer_irq
-	 nop
+	 move	a0, sp			# delay slot
 1:
 	j	ret_from_irq
-	 nop
+	 nop				# delay slot
 	END(indyIRQ)
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-mc.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-mc.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-mc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-mc.c	Thu Sep 12 20:01:40 2002
@@ -16,10 +16,15 @@
 
 /* #define DEBUG_SGIMC */
 
+#ifdef DEBUG_SGIMC
+extern void prom_printf(char *fmt, ...);
+#endif
+
 struct sgimc_misc_ctrl *mcmisc_regs;
 struct sgimc_dma_ctrl *dmactrlregs;
 u32 *rpsscounter;
 
+#ifdef DEBUG_SGIMC
 static inline char *mconfig_string(unsigned long val)
 {
 	switch(val & SGIMC_MCONFIG_RMASK) {
@@ -45,6 +50,7 @@
 		return "wheee, unknown";
 	}
 }
+#endif
 
 void __init sgimc_init(void)
 {
@@ -82,12 +88,12 @@
 	/* 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 = mcmisc_regs->cpuctrl0;
 	tmpreg &= ~SGIMC_CCTRL0_WDOG;
 	mcmisc_regs->cpuctrl0 = tmpreg;
 
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-reset.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-reset.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-reset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-reset.c	Thu Sep 12 20:01:40 2002
@@ -58,7 +58,7 @@
 static void sgi_machine_power_off(void)
 {
 	unsigned char val;
-	
+
 	cli();
 
 	/* Disable watchdog */
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-sc.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-sc.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-sc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-sc.c	Thu Sep 12 20:01:40 2002
@@ -34,7 +34,8 @@
 	unsigned long tmp;
 
 	__asm__ __volatile__(
-	".set\tnoreorder\t\t\t# indy_sc_wipe\n\t"
+	".set\tpush\t\t\t# indy_sc_wipe\n\t"
+	".set\tnoreorder\n\t"
 	".set\tmips3\n\t"
 	".set\tnoat\n\t"
 	"mfc0\t%2, $12\n\t"
@@ -48,12 +49,11 @@
 
 	"1:\tsw\t$0, 0(%0)\n\t"
 	"bne\t%0, %1, 1b\n\t"
-	"daddu\t%0, 32\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"
+	".set\tpop"
 	: "=r" (first), "=r" (last), "=&r" (tmp)
 	: "0" (first), "1" (last));
 }
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-setup.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-setup.c	Thu Sep 12 20:01:40 2002
@@ -28,6 +28,7 @@
 #include <asm/sgi/sgint23.h>
 #include <asm/time.h>
 #include <asm/gdb-stub.h>
+#include <asm/io.h>
 #include <asm/traps.h>
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -133,9 +134,7 @@
 
 void __init ip22_setup(void)
 {
-#ifdef CONFIG_SERIAL_CONSOLE
 	char *ctype;
-#endif
 #ifdef CONFIG_REMOTE_DEBUG
 	char *kgdb_ttyd;
 #endif
@@ -155,19 +154,27 @@
 #endif
 	conswitchp = NULL;
 
-#ifdef CONFIG_SERIAL_CONSOLE
+	/* Set the IO space to some sane value */
+	set_io_port_base (KSEG1ADDR (0x00080000));
+
 	/* 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");
+	if (*ctype == 'd') {
+#ifdef CONFIG_SERIAL_CONSOLE
+		if(*(ctype + 1) == '2')
+			console_setup("ttyS1");
 		else
-			console_setup ("ttyS0");
-	}
+			console_setup("ttyS0");
+#endif
+	} else {
+#ifdef CONFIG_ARC_CONSOLE
+		prom_flags &= PROM_FLAG_USE_AS_CONSOLE;
+		console_setup("ttyS0");
 #endif
+	}
 
 #ifdef CONFIG_REMOTE_DEBUG
 	kgdb_ttyd = prom_getcmdline();
@@ -190,20 +197,19 @@
 	}
 #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
+	{
+		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);
+	}
 	/* newport addresses? */
 	if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) {
 		conswitchp = &newport_con;
@@ -223,9 +229,11 @@
 		conswitchp = &dummy_con;
 	}
 #else
+#ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
 #endif
+#endif
 
 	rtc_ops = &indy_rtc_ops;
 	kbd_ops = &sgi_kbd_ops;
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-system.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-system.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-system.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-system.c	Thu Sep 12 20:01:40 2002
@@ -34,7 +34,7 @@
 
 static int __init string_to_cpu(char *s)
 {
-	long cnt;
+	ULONG cnt;
 	char c;
 	int i;
 
@@ -57,7 +57,7 @@
 {
 	pcomponent *p, *toplev, *cpup = 0;
 	int cputype = -1;
-	long cnt;
+	ULONG cnt;
 	char c;
 
 
@@ -79,9 +79,9 @@
 				ArcRead(0, &c, 1, &cnt);
 				ArcEnterInteractiveMode();
 			}
-			printk("CPU: %s ", p->iname);
+			printk("CPU: %s ", (char *)p->iname);
 			cpup = p;
-			cputype = string_to_cpu(cpup->iname);
+			cputype = string_to_cpu((char *)cpup->iname);
 		}
 		p = ArcGetPeer(p);
 	}
@@ -97,7 +97,7 @@
 		case processor:
 			switch(p->type) {
 			case Fpu:
-				printk("FPU<%s> ", p->iname);
+				printk("FPU<%s> ", (char *)p->iname);
 				break;
 
 			default:
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-time.c linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-time.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip22/ip22-time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sgi-ip22/ip22-time.c	Thu Sep 12 20:01:40 2002
@@ -3,10 +3,10 @@
  * 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 
+ * 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 
+ * Copyright (C) 2001 by Ladislav Michl
  */
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
@@ -28,7 +28,7 @@
  * uses 0 to 11.
  */
 static unsigned long indy_rtc_get_time(void)
-{	
+{
 	unsigned char yrs, mon, day, hrs, min, sec;
 	unsigned char save_control;
 
@@ -97,8 +97,8 @@
 static unsigned long dosample(volatile unsigned char *tcwp,
 			      volatile unsigned char *tc2p)
 {
-	unsigned long ct0, ct1;
-	unsigned char msb, lsb;
+	u32 ct0, ct1;
+	volatile u8 msb, lsb;
 
 	/* Start the counter. */
 	*tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
@@ -127,8 +127,8 @@
 	return ((ct1 - ct0) / 5000) * 5000;
 }
 
-/* 
- * Here we need to calibrate the cycle counter to at least be close. 
+/*
+ * Here we need to calibrate the cycle counter to at least be close.
  */
 void indy_time_init(void)
 {
@@ -165,7 +165,7 @@
 	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] 
+		if (r4k_ticks[2] == r4k_ticks[0]
 		    || r4k_ticks[2] == r4k_ticks[1])
 			r4k_tick = r4k_ticks[2];
 		else {
@@ -179,12 +179,12 @@
 	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;	
-	
+	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 
+	 * Doing it from ip22_setup wouldn't work since traps aren't
 	 * initialized yet.
 	 */
 	sgigio_init();
@@ -225,7 +225,7 @@
 static void indy_timer_setup(struct irqaction *irq)
 {
 	unsigned long count;
-	
+
 	/* over-write the handler, we use our own way */
 	irq->handler = no_action;
 
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/Makefile linux-2.4.20-pre7/arch/mips/sgi-ip27/Makefile
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,15 @@
+#
+# Makefile for the IP27 specific kernel interface routines under Linux.
+#
+
+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-reset.o ip27-setup.o ip27-timer.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/TODO linux-2.4.20-pre7/arch/mips/sgi-ip27/TODO
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/TODO	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/TODO	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,23 @@
+1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
+not to write to the IOC3 ever.
+2. Need to figure out RRB allocation in bridge_startup().
+3. Need to figure out why address swaizzling is needed in inw/outw for
+Qlogic scsi controllers.
+4. Need to integrate ip27-klconfig.c:find_lboard and
+ip27-init.c:find_lbaord_real. DONE
+5. Is it okay to set calias space on all nodes as 0, instead of 8k as
+in irix?
+6. Investigate why things do not work without the setup_test() call
+being invoked on all nodes in ip27-memory.c.
+7. Too many CLIs in the locore handlers :
+For the low level handlers set up by set_except_vector(),
+__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
+investigate whether the code should do CLI, STI or KMODE.
+8. Too many do_page_faults invoked - investigate.
+9. start_thread must turn off UX64 ... and define tlb_refill_debug.
+10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
+does not agree with pgd_bad/pmd_bad.
+11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node.
+This might need to change later. Only the timer intr is set up to be
+received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
+13. Cache flushing (specially the SMP version) has to be investigated.
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-berr.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-berr.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-berr.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-berr.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,93 @@
+/*
+ * This file is subject to 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
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
+#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);
+
+static void dump_hub_information(unsigned long errst0, unsigned long errst1)
+{
+	static char *err_type[2][8] = {
+		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
+		  NULL, NULL, NULL, NULL },
+		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
+		  NULL, NULL, NULL, NULL }
+	};
+	int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
+
+	if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
+		printk("Hub does not contain valid error information\n");
+		return;
+	}
+
+
+	printk("Hub has valid error information:\n");
+	if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
+		printk("Overrun is set.  Error stack may contain additional "
+		       "information.\n");
+	printk("Hub error address is %08lx\n",
+	       (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
+	printk("Incoming message command 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
+	printk("Supplemental field of incoming message is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
+	printk("T5 Rn (for RRB only) is 0x%lx\n",
+	       (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
+	printk("Error type is %s\n", err_type[wrb]
+	       [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
+		? : "invalid");
+}
+
+int be_ip27_handler(struct pt_regs *regs, int is_fixup)
+{
+	unsigned long errst0, errst1;
+	int data = regs->cp0_cause & 4;
+	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+
+	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);
+	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
+	dump_hub_information(errst0, errst1);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+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;
+
+	be_board_handler = be_ip27_handler;
+
+	LOCAL_HUB_S(PI_ERR_INT_PEND,
+	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
+	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
+	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
+	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-console.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-console.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-console.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-console.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,58 @@
+/*
+ * This file is subject to 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 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/sn_private.h>
+
+void prom_putchar(char c)
+{
+	struct ioc3 *ioc3;
+	struct ioc3_uartregs *uart;
+
+	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base;
+	uart = &ioc3->sregs.uarta;
+
+	while ((uart->iu_lsr & 0x20) == 0);
+	uart->iu_thr = c;
+}
+
+char __init prom_getchar(void)
+{
+	return 0;
+}
+
+static void
+ip27prom_console_write(struct console *con, const char *s, unsigned n)
+{
+	prom_printf("%s", s);
+}
+
+static kdev_t
+ip27prom_console_dev(struct console *c)
+{
+	return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console ip27_prom_console = {
+    name:	"prom",
+    write:	ip27prom_console_write,
+    device:	ip27prom_console_dev,
+    flags:	CON_PRINTBUFFER,
+    index:	-1,
+};
+
+__init void ip27_setup_console(void)
+{
+	register_console(&ip27_prom_console);
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-init.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-init.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-init.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-init.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,838 @@
+/*
+ * This file is subject to 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 Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#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>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/intr.h>
+#include <asm/current.h>
+#include <asm/smp.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+#include <asm/sn/launch.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/gda.h>
+
+#define CPU_NONE		(cpuid_t)-1
+
+/*
+ * The following should work till 64 nodes, ie 128p SN0s.
+ */
+#define CNODEMASK_CLRALL(p)	(p) = 0
+#define CNODEMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
+#define CNODEMASK_SETB(p, bit)	((p) |= 1ULL << (bit))
+
+cpumask_t	boot_cpumask;
+hubreg_t	region_mask = 0;
+static int	fine_mode = 0;
+int		maxcpus;
+static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
+static cnodemask_t hub_init_mask;
+static atomic_t numstarted = ATOMIC_INIT(1);
+static int router_distance;
+nasid_t master_nasid = INVALID_NASID;
+
+cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
+nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
+cnodeid_t	cpuid_to_compact_node[MAXCPUS];
+char		node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+
+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;
+}
+
+static void gen_region_mask(hubreg_t *region_mask, int maxnodes)
+{
+	cnodeid_t cnode;
+
+	(*region_mask) = 0;
+	for (cnode = 0; cnode < maxnodes; cnode++) {
+		(*region_mask) |= 1ULL << get_region(cnode);
+	}
+}
+
+int is_fine_dirmode(void)
+{
+	return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
+		>> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
+}
+
+nasid_t get_actual_nasid(lboard_t *brd)
+{
+	klhub_t *hub;
+
+	if (!brd)
+		return INVALID_NASID;
+
+	/* find out if we are a completely disabled brd. */
+	hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
+	if (!hub)
+		return INVALID_NASID;
+	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
+		return hub->hub_info.physid;
+	else
+		return brd->brd_nasid;
+}
+
+/* Tweak this for maximum number of CPUs to activate */
+static int max_cpus = NR_CPUS;
+
+int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask,
+							int *highest)
+{
+	static int tot_cpus_found = 0;
+	lboard_t *brd;
+	klcpu_t *acpu;
+	int cpus_found = 0;
+	cpuid_t cpuid;
+
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+
+	do {
+		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
+		while (acpu) {
+			cpuid = acpu->cpu_info.virtid;
+			/* cnode is not valid for completely disabled brds */
+			if (get_actual_nasid(brd) == brd->brd_nasid)
+				cpuid_to_compact_node[cpuid] = cnode;
+			if (cpuid > *highest)
+				*highest = cpuid;
+			/* Only let it join in if it's marked enabled */
+			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
+						(tot_cpus_found != max_cpus)) {
+				CPUMASK_SETB(*boot_cpumask, cpuid);
+				cpus_found++;
+				tot_cpus_found++;
+			}
+			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+								KLSTRUCT_CPU);
+		}
+		brd = KLCF_NEXT(brd);
+		if (brd)
+			brd = find_lboard(brd,KLTYPE_IP27);
+		else
+			break;
+	} while (brd);
+
+	return cpus_found;
+}
+
+cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes)
+{
+	int i, cpus = 0, highest = 0;
+	gda_t *gdap = GDA;
+	nasid_t nasid;
+
+	/*
+	 * Initialize the arrays to invalid nodeid (-1)
+	 */
+	for (i = 0; i < MAX_COMPACT_NODES; i++)
+		compact_to_nasid_node[i] = INVALID_NASID;
+	for (i = 0; i < MAX_NASIDS; i++)
+		nasid_to_compact_node[i] = INVALID_CNODEID;
+	for (i = 0; i < MAXCPUS; i++)
+		cpuid_to_compact_node[i] = INVALID_CNODEID;
+
+	*numnodes = 0;
+	for (i = 0; i < MAX_COMPACT_NODES; i++) {
+		if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) {
+			break;
+		} else {
+			compact_to_nasid_node[i] = nasid;
+			nasid_to_compact_node[nasid] = i;
+			(*numnodes)++;
+			cpus += do_cpumask(i, nasid, boot_cpumask, &highest);
+		}
+	}
+
+	/*
+	 * Cpus are numbered in order of cnodes. Currently, disabled
+	 * cpus are not numbered.
+	 */
+
+	return(highest + 1);
+}
+
+int cpu_enabled(cpuid_t cpu)
+{
+	if (cpu == CPU_NONE)
+		return 0;
+	return (CPUMASK_TSTB(boot_cpumask, cpu) != 0);
+}
+
+void mlreset (void)
+{
+	int i;
+	void init_topology_matrix(void);
+	void dump_topology(void);
+
+
+	master_nasid = get_nasid();
+	fine_mode = is_fine_dirmode();
+
+	/*
+	 * Probe for all CPUs - this creates the cpumask and
+	 * sets up the mapping tables.
+	 */
+	CPUMASK_CLRALL(boot_cpumask);
+	maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
+	printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes);
+
+	init_topology_matrix();
+	dump_topology();
+
+	gen_region_mask(&region_mask, numnodes);
+	CNODEMASK_CLRALL(hub_init_mask);
+
+	setup_replication_mask(numnodes);
+
+	/*
+	 * Set all nodes' calias sizes to 8k
+	 */
+	for (i = 0; i < numnodes; i++) {
+		nasid_t nasid;
+
+		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.
+		 */
+		REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
+#else
+		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
+#endif
+
+#ifdef LATER
+		/*
+		 * Set up all hubs to have 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
+	}
+}
+
+
+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))
+				LOCAL_HUB_CLR_INTR(base_level + i);
+}
+
+void intr_clear_all(nasid_t nasid)
+{
+	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
+	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
+	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
+		INT_PEND0_BASELVL, "INT_PEND0");
+	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
+		INT_PEND1_BASELVL, "INT_PEND1");
+}
+
+void sn_mp_setup(void)
+{
+	cnodeid_t	cnode;
+#if 0
+	cpuid_t		cpu;
+#endif
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+#if 0
+		init_platform_nodepda();
+#endif
+		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+	}
+#if 0
+	for (cpu = 0; cpu < maxcpus; cpu++) {
+		init_platform_pda();
+	}
+#endif
+}
+
+void per_hub_init(cnodeid_t cnode)
+{
+	extern void pcibr_setup(cnodeid_t);
+	cnodemask_t	done;
+	nasid_t		nasid;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	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);
+		/*
+	 	 * Do the actual initialization if it hasn't been done yet.
+	 	 * We don't need to hold a lock for this work.
+	 	 */
+		/*
+		 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
+		 */
+		REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
+		REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+		hub_rtc_init(cnode);
+		pcibr_setup(cnode);
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+		/*
+		 * If this is not a headless node initialization,
+		 * copy over the caliased exception handlers.
+		 */
+		if (get_compact_nodeid() == cnode) {
+			extern char except_vec0, except_vec1_r10k;
+			extern char except_vec2_generic, except_vec3_generic;
+
+			memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic,
+								0x80);
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
+								0x80);
+			memcpy((void *)KSEG0, &except_vec0, 0x80);
+			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
+			memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
+			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
+								0x100);
+			flush_cache_l1();
+			flush_cache_l2();
+		}
+#endif
+	}
+	spin_unlock(&hub_mask_lock);
+}
+
+/*
+ * This is similar to hard_smp_processor_id().
+ */
+cpuid_t getcpuid(void)
+{
+	klcpu_t *klcpu;
+
+	klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
+	return klcpu->cpu_info.virtid;
+}
+
+void per_cpu_init(void)
+{
+	extern void install_cpu_nmi_handler(int slice);
+	extern void load_mmu(void);
+	static int is_slave = 0;
+	int cpu = smp_processor_id();
+	cnodeid_t cnode = get_compact_nodeid();
+
+	TLBMISS_HANDLER_SETUP();
+#if 0
+	intr_init();
+#endif
+	clear_cp0_status(ST0_IM);
+	per_hub_init(cnode);
+	cpu_time_init();
+	if (smp_processor_id())	/* master can't do this early, no kmalloc */
+		install_cpuintr(cpu);
+	/* Install our NMI handler if symmon hasn't installed one. */
+	install_cpu_nmi_handler(cputoslice(cpu));
+#if 0
+	install_tlbintr(cpu);
+#endif
+	set_cp0_status(SRB_DEV0 | SRB_DEV1);
+	if (is_slave) {
+		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);
+	} else {
+		is_slave = 1;
+	}
+}
+
+cnodeid_t get_compact_nodeid(void)
+{
+	nasid_t nasid;
+
+	nasid = get_nasid();
+	/*
+	 * Map the physical node id to a virtual node id (virtual node ids
+	 * are contiguous).
+	 */
+	return NASID_TO_COMPACT_NODEID(nasid);
+}
+
+#ifdef CONFIG_SMP
+
+/*
+ * Takes as first input the PROM assigned cpu id, and the kernel
+ * assigned cpu id as the second.
+ */
+static void alloc_cpupda(cpuid_t cpu, int cpunum)
+{
+	cnodeid_t	node;
+	nasid_t		nasid;
+
+	node = get_cpu_cnode(cpu);
+	nasid = COMPACT_TO_NASID_NODEID(node);
+
+	cputonasid(cpunum) = nasid;
+	cputocnode(cpunum) = node;
+	cputoslice(cpunum) = get_cpu_slice(cpu);
+	cpu_data[cpunum].p_cpuid = cpu;
+}
+
+static volatile cpumask_t boot_barrier;
+
+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
+	local_flush_tlb_all();
+	flush_cache_l1();
+	flush_cache_l2();
+	start_secondary();
+}
+
+__init void allowboot(void)
+{
+	int		num_cpus = 0;
+	cpuid_t		cpu, mycpuid = getcpuid();
+	cnodeid_t	cnode;
+	extern void	smp_bootstrap(void);
+
+	sn_mp_setup();
+	/* Master has already done per_cpu_init() */
+	install_cpuintr(smp_processor_id());
+#if 0
+	bte_lateinit();
+	ecc_init();
+#endif
+
+	replicate_kernel_text(numnodes);
+	boot_barrier = boot_cpumask;
+	/* Launch slaves. */
+	for (cpu = 0; cpu < maxcpus; cpu++) {
+		if (cpu == mycpuid) {
+			alloc_cpupda(cpu, num_cpus);
+			num_cpus++;
+			/* We're already started, clear our bit */
+			CPUMASK_CLRB(boot_barrier, cpu);
+			continue;
+		}
+
+		/* Skip holes in CPU space */
+		if (CPUMASK_TSTB(boot_cpumask, cpu)) {
+			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", num_cpus);
+			init_tasks[num_cpus] = p;
+			alloc_cpupda(cpu, num_cpus);
+			del_from_runqueue(p);
+			p->processor = num_cpus;
+			p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */
+			unhash_process(p);
+			/* Attach to the address space of init_task. */
+			atomic_inc(&init_mm.mm_count);
+			p->active_mm = &init_mm;
+
+			/*
+		 	 * 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(smp_bootstrap),
+				0, (void *)((unsigned long)p +
+				KERNEL_STACK_SIZE - 32), (void *)p);
+
+			/*
+			 * Now optimistically set the mapping arrays. We
+			 * need to wait here, verify the cpu booted up, then
+			 * fire up the next cpu.
+			 */
+			__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,
+			 * and discover the io devices it will control.
+			 *
+			 * XXX: We really want to fire up launch all the CPUs
+			 * at once.  We have to preserve the order of the
+			 * devices on the bridges first though.
+			 */
+			while(atomic_read(&numstarted) != num_cpus);
+		}
+	}
+
+
+#ifdef LATER
+	Wait logic goes here.
+#endif
+	for (cnode = 0; cnode < numnodes; cnode++) {
+#if 0
+		if (cnodetocpu(cnode) == -1) {
+			printk("Initializing headless hub,cnode %d", cnode);
+			per_hub_init(cnode);
+		}
+#endif
+	}
+#if 0
+	cpu_io_setup();
+	init_mfhi_war();
+#endif
+	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 __init start_secondary(void)
+{
+	/* XXX Why do we need this empty definition at all?  */
+}
+#endif /* CONFIG_SMP */
+
+
+#define	rou_rflag	rou_flags
+
+void
+router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
+{
+	klrou_t *router;
+	lboard_t *brd;
+	int	port;
+
+	if (router_a->rou_rflag == 1)
+		return;
+
+	if (depth >= router_distance)
+		return;
+
+	router_a->rou_rflag = 1;
+
+	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+		if (router_a->rou_port[port].port_nasid == INVALID_NASID)
+			continue;
+
+		brd = (lboard_t *)NODE_OFFSET_TO_K0(
+			router_a->rou_port[port].port_nasid,
+			router_a->rou_port[port].port_offset);
+
+		if (brd->brd_type == KLTYPE_ROUTER) {
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			if (router == router_b) {
+				if (depth < router_distance)
+					router_distance = depth;
+			}
+			else
+				router_recurse(router, router_b, depth + 1);
+		}
+	}
+
+	router_a->rou_rflag = 0;
+}
+
+int
+node_distance(nasid_t nasid_a, nasid_t nasid_b)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	klrou_t *router, *router_a = NULL, *router_b = NULL;
+
+	/* Figure out which routers nodes in question are connected to */
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+			router->rou_rflag = 0;
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27) {
+					if (dest_brd->brd_nasid == nasid_a)
+						router_a = router;
+					if (dest_brd->brd_nasid == nasid_b)
+						router_b = router;
+				}
+			}
+
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+
+	if (router_a == NULL) {
+		printk("node_distance: router_a NULL\n");
+		return -1;
+	}
+	if (router_b == NULL) {
+		printk("node_distance: router_b NULL\n");
+		return -1;
+	}
+
+	if (nasid_a == nasid_b)
+		return 0;
+
+	if (router_a == router_b)
+		return 1;
+
+	router_distance = 100;
+	router_recurse(router_a, router_b, 2);
+
+	return router_distance;
+}
+
+void
+init_topology_matrix(void)
+{
+	nasid_t nasid, nasid2;
+	cnodeid_t row, col;
+
+	for (row = 0; row < MAX_COMPACT_NODES; row++)
+		for (col = 0; col < MAX_COMPACT_NODES; col++)
+			node_distances[row][col] = -1;
+
+	for (row = 0; row < numnodes; row++) {
+		nasid = COMPACT_TO_NASID_NODEID(row);
+		for (col = 0; col < numnodes; col++) {
+			nasid2 = COMPACT_TO_NASID_NODEID(col);
+			node_distances[row][col] = node_distance(nasid, nasid2);
+		}
+	}
+}
+
+void
+dump_topology(void)
+{
+	nasid_t nasid;
+	cnodeid_t cnode;
+	lboard_t *brd, *dest_brd;
+	int port;
+	int router_num = 0;
+	klrou_t *router;
+	cnodeid_t row, col;
+
+	printk("************** Topology ********************\n");
+
+	printk("    ");
+	for (col = 0; col < numnodes; col++)
+		printk("%02d ", col);
+	printk("\n");
+	for (row = 0; row < numnodes; row++) {
+		printk("%02d  ", row);
+		for (col = 0; col < numnodes; col++)
+			printk("%2d ", node_distances[row][col]);
+		printk("\n");
+	}
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		if (nasid == -1) continue;
+
+		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+					KLTYPE_ROUTER);
+
+		if (!brd)
+			continue;
+
+		do {
+			if (brd->brd_flags & DUPLICATE_BOARD)
+				continue;
+			printk("Router %d:", router_num);
+			router_num++;
+
+			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+
+			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+				if (router->rou_port[port].port_nasid == INVALID_NASID)
+					continue;
+
+				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+					router->rou_port[port].port_nasid,
+					router->rou_port[port].port_offset);
+
+				if (dest_brd->brd_type == KLTYPE_IP27)
+					printk(" %d", dest_brd->brd_nasid);
+				if (dest_brd->brd_type == KLTYPE_ROUTER)
+					printk(" r");
+			}
+			printk("\n");
+
+		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+	}
+}
+
+#if 0
+#define		brd_widgetnum	brd_slot
+#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
+void
+dump_klcfg(void)
+{
+	cnodeid_t       cnode;
+	int i;
+	nasid_t         nasid;
+	lboard_t        *lbptr;
+	gda_t           *gdap;
+
+	gdap = (gda_t *)GDA_ADDR(get_nasid());
+	if (gdap->g_magic != GDA_MAGIC) {
+		printk("dumpklcfg_cmd: Invalid GDA MAGIC\n");
+		return;
+	}
+
+	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
+		nasid = gdap->g_nasidtable[cnode];
+
+		if (nasid == INVALID_NASID)
+			continue;
+
+		printk("\nDumpping klconfig Nasid %d:\n", nasid);
+
+		lbptr = KL_CONFIG_INFO(nasid);
+
+		while (lbptr) {
+			printk("    %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx",
+				"board name here", /* BOARD_NAME(lbptr->brd_type), */
+				lbptr->brd_nasid, lbptr->brd_module,
+				lbptr->brd_widgetnum,
+				lbptr->brd_partition,
+				(lbptr->brd_nic), lbptr);
+			if (lbptr->brd_flags & DUPLICATE_BOARD)
+				printk(" -D");
+			printk("\n");
+			for (i = 0; i < lbptr->brd_numcompts; i++) {
+				klinfo_t *kli;
+				kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]);
+				printk("        type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n",
+					kli->struct_type,
+					kli->flags,
+					kli->diagval,
+					kli->physid,
+					kli->virtid,
+					"comp. name here");
+					/* COMPONENT_NAME(kli->struct_type)); */
+			}
+			lbptr = KLCF_NEXT(lbptr);
+		}
+	}
+	printk("\n");
+
+	/* Useful to print router maps also */
+
+	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
+		klrou_t *kr;
+		int i;
+
+        	nasid = gdap->g_nasidtable[cnode];
+        	if (nasid == INVALID_NASID)
+            		continue;
+        	lbptr = KL_CONFIG_INFO(nasid);
+
+        	while (lbptr) {
+
+			lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER);
+			if(!lbptr)
+				break;
+			if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) {
+				printk("%llx -> \n", lbptr->brd_nic);
+				kr = (klrou_t *)find_first_component(lbptr,
+					KLSTRUCT_ROU);
+				for (i = 1; i <= MAX_ROUTER_PORTS; i++) {
+					printk("[%d, %llx]; ",
+						kr->rou_port[i].port_nasid,
+						kr->rou_port[i].port_offset);
+				}
+				printk("\n");
+			}
+			lbptr = KLCF_NEXT(lbptr);
+        	}
+        	printk("\n");
+    	}
+
+	dump_topology();
+}
+#endif
+
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-irq-glue.S linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-irq-glue.S
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-irq-glue.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-irq-glue.S	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,64 @@
+/*
+ * This file is subject to 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 <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+	.text
+	.set	noat
+	.align	5
+NESTED(ip27_irq, PT_SIZE, sp)
+	SAVE_ALL
+	CLI
+	.set	at
+
+	/* IP27 may signal interrupt which we're not interested in.
+	   Mask them out.  */
+	mfc0	s0, CP0_CAUSE
+	mfc0	t0, CP0_STATUS
+	and	s0, t0
+
+	/* First check for RT interrupt.  */
+	andi	a0, s0, CAUSEF_IP4
+	beqz	a0, 1f
+
+	/* Ok, a timer interrupt. */
+	move	a0, sp
+	jal	rt_timer_interrupt
+
+	j	ret_from_irq
+
+1:	andi	a0, s0, (CAUSEF_IP2 | CAUSEF_IP3)
+	beqz	a0, 1f
+
+	/* ... a device interrupt ...  */
+	move	a0, sp
+	jal	ip27_do_irq
+
+	j	ret_from_irq
+
+1:
+#if 1
+	mfc0	a1, CP0_STATUS
+	srl	a1, a1, 8
+	andi	a1, 0xff
+
+	mfc0	a2, CP0_CAUSE
+	srl	a2, a2, 8
+	andi	a2, 0xff
+
+	move	a3, s0
+	PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n")
+	ld	a1, PT_EPC(sp)
+0:	b	0b
+#endif
+
+	j	ret_from_irq
+	END(ip27_irq)
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-irq.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-irq.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-irq.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,487 @@
+/*
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999 - 2001 Kanoj Sarcar
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.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_lock.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#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)
+#else
+#define DBG(x...)
+#endif
+
+/* These should die */
+unsigned char bus_to_wid[256];	/* widget id for linux pci bus */
+unsigned char bus_to_nid[256];	/* nasid for linux pci bus */
+unsigned char num_bridges;	/* number of bridges in the system */
+
+/*
+ * 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.
+ */
+
+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);
+
+/*
+ * 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.
+ */
+int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS];
+
+/*
+ * use these macros to get the encoded nasid and widget id
+ * from the irq value
+ */
+#define IRQ_TO_BUS(i)			irq_to_bus[(i)]
+#define IRQ_TO_CPU(i)			bus_to_cpu[IRQ_TO_BUS(i)]
+#define NASID_FROM_PCI_IRQ(i)		bus_to_nid[IRQ_TO_BUS(i)]
+#define WID_FROM_PCI_IRQ(i)		bus_to_wid[IRQ_TO_BUS(i)]
+#define	SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
+
+static inline int alloc_level(cpuid_t cpunum, int irq)
+{
+	cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum);
+	int j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
+
+	while (++j < PERNODE_LEVELS) {
+		if (node_level_to_irq[nodenum][j] == -1) {
+			node_level_to_irq[nodenum][j] = irq;
+			return j;
+		}
+	}
+	printk("Cpu %ld flooded with devices\n", cpunum);
+	while(1);
+	return -1;
+}
+
+static inline int find_level(cpuid_t *cpunum, int irq)
+{
+	int j;
+	cnodeid_t nodenum = INVALID_CNODEID;
+
+	while (++nodenum < MAX_COMPACT_NODES) {
+		j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
+		while (++j < PERNODE_LEVELS)
+			if (node_level_to_irq[nodenum][j] == irq) {
+				*cpunum = 0;	/* XXX Fixme */
+				return(j);
+			}
+	}
+	printk("Could not identify cpu/level for irq %d\n", irq);
+	while(1);
+	return(-1);
+}
+
+/*
+ * Find first bit set
+ */
+static int ms1bit(unsigned long x)
+{
+	int b = 0, 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;
+}
+
+/*
+ * This code is unnecessarily complex, because we do SA_INTERRUPT
+ * intr enabling. Basically, once we grab the set of intrs we need
+ * to service, we must mask _all_ these interrupts; firstly, to make
+ * sure the same intr does not intr again, causing recursion that
+ * can lead to stack overflow. Secondly, we can not just mask the
+ * one intr we are do_IRQing, because the non-masked intrs in the
+ * first set might intr again, causing multiple servicings of the
+ * same intr. This effect is mostly seen for intercpu intrs.
+ * Kanoj 05.13.00
+ */
+void ip27_do_irq(struct pt_regs *regs)
+{
+	int irq, swlevel;
+	hubreg_t pend0, mask0;
+	cpuid_t thiscpu = smp_processor_id();
+	int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ?
+					PI_INT_MASK0_A : PI_INT_MASK0_B);
+
+	/* copied from Irix intpend0() */
+	while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) &
+				(mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) {
+		pend0 &= mask0;		/* Pick intrs we should look at */
+		if (pend0) {
+			/* Prevent any of the picked intrs from recursing */
+			LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0));
+			do {
+				swlevel = ms1bit(pend0);
+				LOCAL_HUB_CLR_INTR(swlevel);
+				/* "map" swlevel to irq */
+				irq = LEVEL_TO_IRQ(thiscpu, swlevel);
+				do_IRQ(irq, regs);
+				/* clear bit in pend0 */
+				pend0 ^= 1ULL << swlevel;
+			} while(pend0);
+			/* Now allow the set of serviced intrs again */
+			LOCAL_HUB_S(pi_int_mask0, mask0);
+			LOCAL_HUB_L(PI_INT_PEND0);
+		}
+	}
+}
+
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int startup_bridge_irq(unsigned int irq)
+{
+	bridgereg_t device;
+	bridge_t *bridge;
+	int pin, swlevel;
+	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);
+
+	DBG("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
+	/*
+	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = alloc_level(cpu, irq);
+	intr_connect_level(cpu, swlevel);
+
+	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8));
+	bridge->b_int_enable |= (1 << pin);
+	/* more stuff in int_enable reg */
+	bridge->b_int_enable |= 0x7ffffe00;
+
+	/*
+	 * XXX This only works if b_int_device is initialized to 0!
+	 * We program the bridge to have a 1:1 mapping between devices
+	 * (slots) and intr pins.
+	 */
+	device = bridge->b_int_device;
+	device |= (pin << (pin*3));
+	bridge->b_int_device = device;
+
+        bridge->b_widget.w_tflush;                      /* Flush */
+
+        return 0;       /* Never anything pending.  */
+}
+
+/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
+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);
+	pin = SLOT_FROM_PCI_IRQ(irq);
+
+	/*
+	 * map irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = find_level(&cpu, irq);
+	intr_disconnect_level(cpu, swlevel);
+	LEVEL_TO_IRQ(cpu, swlevel) = -1;
+
+	bridge->b_int_enable &= ~(1 << pin);
+	bridge->b_widget.w_tflush;                      /* Flush */
+
+	return 0;       /* Never anything pending.  */
+}
+
+static inline void enable_bridge_irq(unsigned int irq)
+{
+	/* All the braindamage happens magically for us in ip27_do_irq */
+}
+
+static void disable_bridge_irq(unsigned int irq)
+{
+	/* All the braindamage happens magically for us in ip27_do_irq */
+}
+
+static void mask_and_ack_bridge_irq(unsigned int irq)
+{
+	/* All the braindamage happens magically for us in ip27_do_irq */
+}
+
+static void end_bridge_irq (unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_bridge_irq(irq);
+}
+
+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
+};
+
+void irq_debug(void)
+{
+	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));
+}
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	set_except_vector(0, ip27_irq);
+
+	/*
+	 * Right now the bridge irq is our kitchen sink interrupt type
+	 */
+	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;
+	}
+}
+
+/*
+ * 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,
+				hubreg_t **intpend_masks, int *ip)
+{
+	hub_intmasks_t *hub_intmasks;
+
+	hub_intmasks = &cpu_data[cpu].p_intmasks;
+	if (bit < N_INTPEND_BITS) {
+		*intpend_masks = hub_intmasks->intpend0_masks;
+		*ip = 0;
+		*new_bit = bit;
+	} else {
+		*intpend_masks = hub_intmasks->intpend1_masks;
+		*ip = 1;
+		*new_bit = bit - N_INTPEND_BITS;
+	}
+	return hub_intmasks;
+}
+
+int intr_connect_level(int cpu, int bit)
+{
+	int ip;
+	int slice = cputoslice(cpu);
+	volatile hubreg_t *mask_reg;
+	hubreg_t *intpend_masks;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
+
+	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
+
+	/* Make sure it's not already pending when we connect it. */
+	REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS);
+
+	intpend_masks[0] |= (1ULL << (u64)bit);
+
+	if (ip == 0) {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A +
+				PI_INT_MASK_OFFSET * slice);
+	} else {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A +
+				PI_INT_MASK_OFFSET * slice);
+	}
+	HUB_S(mask_reg, intpend_masks[0]);
+	return(0);
+}
+
+int intr_disconnect_level(int cpu, int bit)
+{
+	int ip;
+	int slice = cputoslice(cpu);
+	volatile hubreg_t *mask_reg;
+	hubreg_t *intpend_masks;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
+
+	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
+	intpend_masks[0] &= ~(1ULL << (u64)bit);
+	if (ip == 0) {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A +
+				PI_INT_MASK_OFFSET * slice);
+	} else {
+		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A +
+				PI_INT_MASK_OFFSET * slice);
+	}
+	HUB_S(mask_reg, intpend_masks[0]);
+	return(0);
+}
+
+
+void handle_resched_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* 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)
+{
+#ifdef CONFIG_SMP
+#if (CPUS_PER_NODE == 2)
+	static int done = 0;
+
+	/*
+	 * This is a hack till we have a pernode irqlist. Currently,
+	 * just have the master cpu set up the handlers for the per
+	 * cpu irqs.
+	 */
+	if (done == 0) {
+		int j;
+
+		if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr,
+							0, "resched", 0))
+			panic("intercpu intr unconnectible");
+		if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr,
+							0, "resched", 0))
+			panic("intercpu intr unconnectible");
+		if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt,
+							0, "callfunc", 0))
+			panic("intercpu intr unconnectible");
+		if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt,
+							0, "callfunc", 0))
+			panic("intercpu intr unconnectible");
+
+		for (j = 0; j < PERNODE_LEVELS; j++)
+			LEVEL_TO_IRQ(0, j) = -1;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) =
+							CPU_RESCHED_A_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) =
+							CPU_RESCHED_B_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) =
+							CPU_CALL_A_IRQ;
+		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) =
+							CPU_CALL_B_IRQ;
+		for (j = 1; j < MAX_COMPACT_NODES; j++)
+			memcpy(&node_level_to_irq[j][0],
+			&node_level_to_irq[0][0],
+			sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS);
+
+		done = 1;
+	}
+
+	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ +
+							cputoslice(cpu)));
+	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ +
+							cputoslice(cpu)));
+#else /* CPUS_PER_NODE */
+#error Must redefine this for more than 2 CPUS.
+#endif /* CPUS_PER_NODE */
+#endif /* CONFIG_SMP */
+}
+
+void install_tlbintr(int cpu)
+{
+#if 0
+	int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu);
+
+	intr_connect_level(cpu, intr_bit);
+#endif
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-klconfig.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-klconfig.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-klconfig.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-klconfig.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+
+klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
+{
+	int index, j;
+
+	if (kli == (klinfo_t *)NULL) {
+		index = 0;
+	} else {
+		for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
+			if (kli == KLCF_COMP(brd, j))
+				break;
+		index = j;
+		if (index == KLCF_NUM_COMPS(brd)) {
+			printk("find_component: Bad pointer: 0x%p\n", kli);
+			return (klinfo_t *)NULL;
+		}
+		index++;		/* next component */
+	}
+
+	for (; index < KLCF_NUM_COMPS(brd); index++) {
+		kli = KLCF_COMP(brd, index);
+		if (KLCF_COMP_TYPE(kli) == struct_type)
+			return kli;
+	}
+
+	/* Didn't find it. */
+	return (klinfo_t *)NULL;
+}
+
+klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
+{
+	return find_component(brd, (klinfo_t *)NULL, struct_type);
+}
+
+lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (start->brd_type == brd_type)
+			return start;
+		start = KLCF_NEXT(start);
+	}
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
+{
+	/* Search all boards stored on this node. */
+	while (start) {
+		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
+			return start;
+		start = KLCF_NEXT(start);
+	}
+
+	/* Didn't find it. */
+	return (lboard_t *)NULL;
+}
+
+cnodeid_t get_cpu_cnode(cpuid_t cpu)
+{
+	return CPUID_TO_COMPACT_NODEID(cpu);
+}
+
+klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
+{
+	lboard_t *brd;
+	klcpu_t *acpu;
+
+	if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
+		return (klcpu_t *)NULL;
+
+	if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
+		return (klcpu_t *)NULL;
+
+	do {
+		if ((acpu->cpu_info.physid) == slice)
+			return acpu;
+	} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+								KLSTRUCT_CPU)));
+	return (klcpu_t *)NULL;
+}
+
+klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
+{
+	nasid_t nasid;
+	int slice;
+	klcpu_t *acpu;
+	gda_t *gdap = GDA;
+	cnodeid_t cnode;
+
+	if (!(cpu < MAXCPUS)) {
+		printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
+		return NULL;
+	}
+
+	cnode = get_cpu_cnode(cpu);
+	if (cnode == INVALID_CNODEID)
+		return NULL;
+
+	if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
+		return NULL;
+
+	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+		acpu = nasid_slice_to_cpuinfo(nasid, slice);
+		if (acpu && acpu->cpu_info.virtid == cpu)
+			return acpu;
+	}
+	return NULL;
+}
+
+int get_cpu_slice(cpuid_t cpu)
+{
+	klcpu_t *acpu;
+
+	if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
+		return -1;
+	return acpu->cpu_info.physid;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-klnuma.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-klnuma.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-klnuma.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-klnuma.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,143 @@
+/*
+ * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
+ * Copyright 2000 - 2001 Silicon Graphics, Inc.
+ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mmzone.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/smp.h>
+#include <asm/sn/types.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/mmzone.h>
+#include <asm/sn/klkernvars.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn_private.h>
+
+extern char _end;
+static cpumask_t ktext_repmask;
+
+/*
+ * XXX - This needs to be much smarter about where it puts copies of the
+ * kernel.  For example, we should never put a copy on a headless node,
+ * and we should respect the topology of the machine.
+ */
+void __init setup_replication_mask(int maxnodes)
+{
+	static int 	numa_kernel_replication_ratio;
+	cnodeid_t	cnode;
+
+	/* Set only the master cnode's bit.  The master cnode is always 0. */
+	CPUMASK_CLRALL(ktext_repmask);
+	CPUMASK_SETB(ktext_repmask, 0);
+
+	numa_kernel_replication_ratio = 0;
+#ifdef CONFIG_REPLICATE_KTEXT
+#ifndef CONFIG_MAPPED_KERNEL
+#error Kernel replication works with mapped kernel support. No calias support.
+#endif
+	numa_kernel_replication_ratio = 1;
+#endif
+
+	for (cnode = 1; cnode < numnodes; cnode++) {
+		/* See if this node should get a copy of the kernel */
+		if (numa_kernel_replication_ratio &&
+		    !(cnode % numa_kernel_replication_ratio)) {
+
+			/* Advertise that we have a copy of the kernel */
+			CPUMASK_SETB(ktext_repmask, cnode);
+		}
+	}
+
+	/* Set up a GDA pointer to the replication mask. */
+	GDA->g_ktext_repmask = &ktext_repmask;
+}
+
+
+static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
+{
+	kern_vars_t *kvp;
+	cnodeid_t client_cnode;
+
+	client_cnode = NASID_TO_COMPACT_NODEID(client_nasid);
+
+	kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars);
+
+	KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
+
+	kvp->kv_magic = KV_MAGIC;
+
+	kvp->kv_ro_nasid = server_nasid;
+	kvp->kv_rw_nasid = master_nasid;
+	kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
+	kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
+	printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid);
+}
+
+/* XXX - When the BTE works, we should use it instead of this. */
+static __init void copy_kernel(nasid_t dest_nasid)
+{
+	extern char _stext, _etext;
+	unsigned long dest_kern_start, source_start, source_end, kern_size;
+
+	source_start = (unsigned long)&_stext;
+	source_end = (unsigned long)&_etext;
+	kern_size = source_end - source_start;
+
+	dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
+					    dest_nasid);
+	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
+}
+
+void __init replicate_kernel_text(int maxnodes)
+{
+	cnodeid_t cnode;
+	nasid_t client_nasid;
+	nasid_t server_nasid;
+
+	server_nasid = master_nasid;
+
+	/* Record where the master node should get its kernel text */
+	set_ktext_source(master_nasid, master_nasid);
+
+	for (cnode = 1; cnode < maxnodes; cnode++) {
+		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+		/* Check if this node should get a copy of the kernel */
+		if (CPUMASK_TSTB(ktext_repmask, cnode)) {
+			server_nasid = client_nasid;
+			copy_kernel(server_nasid);
+		}
+
+		/* Record where this node should get its kernel text */
+		set_ktext_source(client_nasid, server_nasid);
+	}
+}
+
+/*
+ * Return pfn of first free page of memory on a node. PROM may allocate
+ * data structures on the first couple of pages of the first slot of each
+ * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
+ */
+pfn_t node_getfirstfree(cnodeid_t cnode)
+{
+	unsigned long loadbase = CKSEG0;
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+	unsigned long offset;
+
+#ifdef CONFIG_MAPPED_KERNEL
+	loadbase = CKSSEG + 16777216;
+#endif
+	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
+	if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode)))
+		return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
+	else
+		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
+								PAGE_SHIFT);
+}
+
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-memory.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-memory.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-memory.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-memory.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,344 @@
+/*
+ * This file is subject to 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 by Ralf Baechle
+ * Copyright (C) 2000 by Silicon Graphics, Inc.
+ *
+ * On SGI IP27 the ARC memory configuration data is completly bogus but
+ * alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/mmzone.h>
+
+/* ip27-klnuma.c   */
+extern pfn_t node_getfirstfree(cnodeid_t cnode);
+
+#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define SLOT_IGNORED	0xffff
+
+short slot_lastfilled_cache[MAX_COMPACT_NODES];
+unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
+static pfn_t numpages;
+
+plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES];
+bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES];
+
+int numa_debug(void)
+{
+	printk("NUMA debug\n");
+	*(int *)0 = 0;
+	return(0);
+}
+
+/*
+ * Return the number of pages of memory provided by the given slot
+ * on the specified node.
+ */
+pfn_t slot_getsize(cnodeid_t node, int slot)
+{
+	return (pfn_t) slot_psize_cache[node][slot];
+}
+
+/*
+ * Return highest slot filled
+ */
+int node_getlastslot(cnodeid_t node)
+{
+	return (int) slot_lastfilled_cache[node];
+}
+
+/*
+ * Return the pfn of the last free page of memory on a node.
+ */
+pfn_t node_getmaxclick(cnodeid_t node)
+{
+	pfn_t	slot_psize;
+	int	slot;
+
+	/*
+	 * Start at the top slot. When we find a slot with memory in it,
+	 * that's the winner.
+	 */
+	for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) {
+		if ((slot_psize = slot_getsize(node, slot))) {
+			if (slot_psize == SLOT_IGNORED)
+				continue;
+			/* Return the basepfn + the slot size, minus 1. */
+			return slot_getbasepfn(node, slot) + slot_psize - 1;
+		}
+	}
+
+	/*
+	 * If there's no memory on the node, return 0. This is likely
+	 * to cause problems.
+	 */
+	return (pfn_t)0;
+}
+
+static pfn_t slot_psize_compute(cnodeid_t node, int slot)
+{
+	nasid_t nasid;
+	lboard_t *brd;
+	klmembnk_t *banks;
+	unsigned long size;
+
+	nasid = COMPACT_TO_NASID_NODEID(node);
+	/* Find the node board */
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+	if (!brd)
+		return 0;
+
+	/* Get the memory bank structure */
+	banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
+	if (!banks)
+		return 0;
+
+	/* Size in _Megabytes_ */
+	size = (unsigned long)banks->membnk_bnksz[slot/4];
+
+	/* hack for 128 dimm banks */
+	if (size <= 128) {
+		if (slot%4 == 0) {
+			size <<= 20;		/* size in bytes */
+			return(size >> PAGE_SHIFT);
+		} else {
+			return 0;
+		}
+	} else {
+		size /= 4;
+		size <<= 20;
+		return(size >> PAGE_SHIFT);
+	}
+}
+
+pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
+{
+	cnodeid_t node;
+	int slot, numslots;
+	pfn_t num_pages = 0, slot_psize;
+	pfn_t slot0sz = 0, nodebytes;	/* Hack to detect problem configs */
+	int ignore;
+
+	for (node = 0; node < numnodes; node++) {
+		numslots = node_getnumslots(node);
+		ignore = nodebytes = 0;
+		for (slot = 0; slot < numslots; slot++) {
+			slot_psize = slot_psize_compute(node, slot);
+			if (slot == 0) slot0sz = slot_psize;
+			/*
+			 * We need to refine the hack when we have replicated
+			 * kernel text.
+			 */
+			nodebytes += SLOT_SIZE;
+			if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
+						(slot0sz << PAGE_SHIFT))
+				ignore = 1;
+			if (ignore && slot_psize) {
+				printk("Ignoring slot %d onwards on node %d\n",
+								slot, node);
+				slot_psize_cache[node][slot] = SLOT_IGNORED;
+				slot = numslots;
+				continue;
+			}
+			num_pages += slot_psize;
+			slot_psize_cache[node][slot] =
+					(unsigned short) slot_psize;
+			if (slot_psize)
+				slot_lastfilled_cache[node] = slot;
+		}
+	}
+	if (maxpmem)
+		return((maxpmem > num_pages) ? num_pages : maxpmem);
+	else
+		return num_pages;
+}
+
+/*
+ * Currently, the intranode memory hole support assumes that each slot
+ * contains at least 32 MBytes of memory. We assume all bootmem data
+ * fits on the first slot.
+ */
+void __init prom_meminit(void)
+{
+	extern void mlreset(void);
+	cnodeid_t node;
+	pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn;
+	unsigned long bootmap_size;
+	int node_datasz;
+
+	node_datasz = PFN_UP(sizeof(plat_pg_data_t));
+	mlreset();
+	numpages = szmem(0, 0);
+	for (node = (numnodes - 1); node >= 0; node--) {
+		slot_firstpfn = slot_getbasepfn(node, 0);
+		slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
+		slot_freepfn = node_getfirstfree(node);
+		/* Foll line hack for non discontigmem; remove once discontigmem
+		 * becomes the default. */
+		max_low_pfn = (slot_lastpfn - slot_firstpfn);
+
+		/*
+		 * Allocate the node data structure on the node first.
+		 */
+		plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \
+							<< PAGE_SHIFT));
+		NODE_DATA(node)->bdata = plat_node_bdata + node;
+		slot_freepfn += node_datasz;
+	  	bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
+						slot_firstpfn, slot_lastpfn);
+		free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+				(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
+		reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+		  ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
+	}
+	printk("Total memory probed : 0x%lx pages\n", numpages);
+}
+
+int __init page_is_ram(unsigned long pagenr)
+{
+        return 1;
+}
+
+void __init
+prom_free_prom_memory (void)
+{
+	/* We got nothing to free here ...  */
+}
+
+#ifdef CONFIG_DISCONTIGMEM
+
+static pfn_t pagenr = 0;
+
+void __init paging_init(void)
+{
+	pmd_t *pmd = kpmdtbl;
+	pte_t *pte = kptbl;
+
+	cnodeid_t node;
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	int i;
+
+	/* Initialize the entire pgd.  */
+	pgd_init((unsigned long)swapper_pg_dir);
+	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
+
+	/* This is for vmalloc  */
+	memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER);
+	memset((void *)kpmdtbl, 0, PAGE_SIZE);
+	pgd_set(swapper_pg_dir, kpmdtbl);
+	for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
+		pmd_val(*pmd) = (unsigned long)pte;
+
+	for (node = 0; node < numnodes; node++) {
+		pfn_t start_pfn = slot_getbasepfn(node, 0);
+		pfn_t end_pfn = node_getmaxclick(node);
+
+		zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
+		free_area_init_node(node, NODE_DATA(node), 0, zones_size,
+						start_pfn << PAGE_SHIFT, 0);
+		if ((PLAT_NODE_DATA_STARTNR(node) +
+					PLAT_NODE_DATA_SIZE(node)) > pagenr)
+			pagenr = PLAT_NODE_DATA_STARTNR(node) +
+					PLAT_NODE_DATA_SIZE(node);
+	}
+}
+
+void __init mem_init(void)
+{
+	extern char _stext, _etext, _fdata, _edata;
+	extern char __init_begin, __init_end;
+	extern unsigned long totalram_pages;
+	extern unsigned long setup_zero_pages(void);
+	cnodeid_t nid;
+	unsigned long tmp;
+	unsigned long codesize, datasize, initsize;
+	int slot, numslots;
+	struct page *pg, *pslot;
+	pfn_t pgnr;
+
+	num_physpages = numpages;	/* memory already sized by szmem */
+	max_mapnr = pagenr;		/* already found during paging_init */
+	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+
+	for (nid = 0; nid < numnodes; nid++) {
+
+		/*
+		 * Hack till free_area_init_core() zeroes free_pages
+		 */
+		for (tmp = 0; tmp < MAX_NR_ZONES; tmp++)
+			PLAT_NODE_DATA(nid)->gendata.node_zones[tmp].free_pages=0;
+		/*
+	 	 * This will free up the bootmem, ie, slot 0 memory.
+	 	 */
+		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
+
+		/*
+		 * We need to manually do the other slots.
+		 */
+		pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
+		pgnr = PLAT_NODE_DATA_STARTNR(nid) + slot_getsize(nid, 0);
+		numslots = node_getlastslot(nid);
+		for (slot = 1; slot <= numslots; slot++) {
+			pslot = NODE_DATA(nid)->node_mem_map +
+			   slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0);
+
+			/*
+			 * Mark holes in previous slot. May also want to
+			 * free up the pages that hold the memmap entries.
+			 */
+			while (pg < pslot) {
+				pg++; pgnr++;
+			}
+
+			/*
+			 * Free valid memory in current slot.
+			 */
+			pslot += slot_getsize(nid, slot);
+			while (pg < pslot) {
+				if (!page_is_ram(pgnr))
+					continue;
+				ClearPageReserved(pg);
+				atomic_set(&pg->count, 1);
+				__free_page(pg);
+				totalram_pages++;
+				pg++; pgnr++;
+			}
+		}
+	}
+
+	totalram_pages -= setup_zero_pages();	/* This comes from node 0 */
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	tmp = (unsigned long) nr_free_pages();
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+		"%ldk data, %ldk init)\n",
+		tmp << (PAGE_SHIFT-10),
+		num_physpages << (PAGE_SHIFT-10),
+		codesize >> 10,
+		(num_physpages - tmp) << (PAGE_SHIFT-10),
+		datasize >> 10,
+		initsize >> 10);
+}
+
+#endif /* CONFIG_DISCONTIGMEM */
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-nmi.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-nmi.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-nmi.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-nmi.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,168 @@
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/atomic.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/nmi.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+
+#if 0
+#define NODE_NUM_CPUS(n)	CNODE_NUM_CPUS(n)
+#else
+#define NODE_NUM_CPUS(n)	CPUS_PER_NODE
+#endif
+
+#define CNODEID_NONE (cnodeid_t)-1
+#define enter_panic_mode()	spin_lock(&nmi_lock)
+
+typedef unsigned long machreg_t;
+
+spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Lets see what else we need to do here. Set up sp, gp?
+ */
+void nmi_dump(void)
+{
+	void cont_nmi_dump(void);
+
+	cont_nmi_dump();
+}
+
+void install_cpu_nmi_handler(int slice)
+{
+	nmi_t *nmi_addr;
+
+	nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
+	if (nmi_addr->call_addr)
+		return;
+	nmi_addr->magic = NMI_MAGIC;
+	nmi_addr->call_addr = (void *)nmi_dump;
+	nmi_addr->call_addr_c =
+		(void *)(~((unsigned long)(nmi_addr->call_addr)));
+	nmi_addr->call_parm = 0;
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+
+void
+nmi_cpu_eframe_save(nasid_t nasid,
+		    int	    slice)
+{
+	int 		i, numberof_nmi_cpu_regs;
+	machreg_t	*prom_format;
+
+	/* Get the total number of registers being saved by the prom */
+	numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t);
+
+	/* Get the pointer to the current cpu's register set. */
+	prom_format =
+	    (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
+			  slice * IP27_NMI_KREGS_CPU_SIZE);
+
+	printk("NMI nasid %d: slice %d\n", nasid, slice);
+	for (i = 0; i < numberof_nmi_cpu_regs; i++)
+		printk("0x%lx  ", prom_format[i]);
+	printk("\n\n");
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+void
+nmi_node_eframe_save(cnodeid_t  cnode)
+{
+	int		cpu;
+	nasid_t		nasid;
+
+	/* Make sure that we have a valid node */
+	if (cnode == CNODEID_NONE)
+		return;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+	if (nasid == INVALID_NASID)
+		return;
+
+	/* Save the registers into eframe for each cpu */
+	for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++)
+		nmi_cpu_eframe_save(nasid, cpu);
+}
+
+/*
+ * Save the nmi cpu registers for all cpus in the system.
+ */
+void
+nmi_eframes_save(void)
+{
+	cnodeid_t	cnode;
+
+	for(cnode = 0 ; cnode < numnodes; cnode++)
+		nmi_node_eframe_save(cnode);
+}
+
+void
+cont_nmi_dump(void)
+{
+#ifndef REAL_NMI_SIGNAL
+	static atomic_t nmied_cpus = ATOMIC_INIT(0);
+
+	atomic_inc(&nmied_cpus);
+#endif
+	/*
+	 * Use enter_panic_mode to allow only 1 cpu to proceed
+	 */
+	enter_panic_mode();
+
+#ifdef REAL_NMI_SIGNAL
+	/*
+	 * Wait up to 15 seconds for the other cpus to respond to the NMI.
+	 * If a cpu has not responded after 10 sec, send it 1 additional NMI.
+	 * This is for 2 reasons:
+	 *	- sometimes a MMSC fail to NMI all cpus.
+	 *	- on 512p SN0 system, the MMSC will only send NMIs to
+	 *	  half the cpus. Unfortunately, we dont know which cpus may be
+	 *	  NMIed - it depends on how the site chooses to configure.
+	 *
+	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to
+	 * send NMIs to all cpus on a 256p system.
+	 */
+	for (i=0; i < 1500; i++) {
+		for (node=0; node < numnodes; node++)
+			if (NODEPDA(node)->dump_count == 0)
+				break;
+		if (node == numnodes)
+			break;
+		if (i == 1000) {
+			for (node=0; node < numnodes; node++)
+				if (NODEPDA(node)->dump_count == 0) {
+					cpu = CNODE_TO_CPU_BASE(node);
+					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
+						CPUMASK_SETB(nmied_cpus, cpu);
+						/*
+						 * cputonasid, cputoslice
+						 * needs kernel cpuid
+						 */
+						SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
+					}
+				}
+
+		}
+		udelay(10000);
+	}
+#else
+	while (atomic_read(&nmied_cpus) != smp_num_cpus);
+#endif
+
+	/*
+	 * Save the nmi cpu registers for all cpu in the eframe format.
+	 */
+	nmi_eframes_save();
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-pci.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-pci.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-pci.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-pci.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,428 @@
+/*
+ * This file is subject to 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, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/sn/arch.h>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * Max #PCI busses we can handle; ie, max #PCI bridges.
+ */
+#define MAX_PCI_BUSSES		40
+
+/*
+ * Max #PCI devices (like scsi controllers) we handle on a bus.
+ */
+#define MAX_DEVICES_PER_PCIBUS	8
+
+/*
+ * No locking needed until PCI initialization is done parallely.
+ */
+int irqstore[MAX_PCI_BUSSES][MAX_DEVICES_PER_PCIBUS];
+int lastirq = BASE_PCI_IRQ;
+
+/*
+ * Translate from irq to software PCI bus number and PCI slot.
+ */
+int irq_to_bus[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+
+/*
+ * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
+ * not really documented, so right now I can't write code which uses it.
+ * Therefore we use type 0 accesses for now even though they won't work
+ * correcly for PCI-to-PCI bridges.
+ */
+#define CF0_READ_PCI_CFG(dev,where,value,bm,mask)			\
+do {									\
+	bridge_t *bridge;                                               \
+	int slot = PCI_SLOT(dev->devfn);				\
+	int fn = PCI_FUNC(dev->devfn);					\
+	volatile u32 *addr;						\
+	u32 cf, __bit;							\
+	unsigned int bus_id = (unsigned) dev->bus->number;              \
+									\
+	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
+                                             bus_to_wid[bus_id]);       \
+                                                                        \
+	if (dev->vendor == PCI_VENDOR_ID_SGI				\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
+	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) {	\
+		*value = 0;						\
+		return PCIBIOS_SUCCESSFUL;				\
+	}								\
+									\
+	__bit = (((where) & (bm)) << 3);				\
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
+	if (get_dbe(cf, addr))						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+	*value = (cf >> __bit) & (mask);				\
+	return PCIBIOS_SUCCESSFUL;					\
+} while (0)
+
+static int
+pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,3,0xff);
+}
+
+static int
+pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,2,0xffff);
+}
+
+static int
+pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff);
+}
+
+#define CF0_WRITE_PCI_CFG(dev,where,value,bm,mask)			\
+do {									\
+	bridge_t *bridge;                                               \
+	int slot = PCI_SLOT(dev->devfn);				\
+	int fn = PCI_FUNC(dev->devfn);					\
+	volatile u32 *addr;						\
+	u32 cf, __bit;							\
+	unsigned int bus_id = (unsigned) dev->bus->number;              \
+									\
+	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
+                                             bus_to_wid[bus_id]);       \
+                                                                        \
+	if (dev->vendor == PCI_VENDOR_ID_SGI				\
+	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
+	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48)))	\
+		return PCIBIOS_SUCCESSFUL;				\
+									\
+	__bit = (((where) & (bm)) << 3);				\
+	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
+	if (get_dbe(cf, addr))						\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+	cf &= (~mask);							\
+	cf |= (value);							\
+	put_dbe(cf, addr);						\
+	return PCIBIOS_SUCCESSFUL;					\
+} while (0)
+
+static int
+pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,3,0xff);
+}
+
+static int
+pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff);
+}
+
+static int
+pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff);
+}
+
+
+static struct pci_ops bridge_pci_ops = {
+	pci_conf0_read_config_byte,
+	pci_conf0_read_config_word,
+	pci_conf0_read_config_dword,
+	pci_conf0_write_config_byte,
+	pci_conf0_write_config_word,
+	pci_conf0_write_config_dword
+};
+
+void __init pcibios_init(void)
+{
+	struct pci_ops *ops = &bridge_pci_ops;
+	int	i;
+
+	ioport_resource.end = ~0UL;
+	iomem_resource.end = ~0UL;
+
+	for (i=0; i<num_bridges; i++) {
+		printk("PCI: Probing PCI hardware on host bus %2d.\n", i);
+		pci_scan_bus(i, ops, NULL);
+	}
+}
+
+static inline u8
+bridge_swizzle(u8 pin, u8 slot)
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+static u8 __init
+pci_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	u8 pin = *pinp;
+
+	while (dev->bus->self) {	/* Move up the chain of bridges. */
+		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+		dev = dev->bus->self;
+	}
+	*pinp = pin;
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/*
+ * All observed requests have pin == 1. We could have a global here, that
+ * gets incremented and returned every time - unfortunately, pci_map_irq
+ * may be called on the same device over and over, and need to return the
+ * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
+ *
+ * A given PCI device, in general, should be able to intr any of the cpus
+ * on any one of the hubs connected to its xbow.
+ */
+static int __init
+pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if ((dev->bus->number >= MAX_PCI_BUSSES)
+	    || (pin != 1)
+	    || (slot >= MAX_DEVICES_PER_PCIBUS))
+		panic("Increase supported PCI busses %d,%d,%d",
+		      dev->bus->number, slot, pin);
+
+	/*
+	 * Already assigned? Then return previously assigned value ...
+	 */
+	if (irqstore[dev->bus->number][slot])
+		return irqstore[dev->bus->number][slot];
+
+	irq_to_bus[lastirq] = dev->bus->number;
+	irq_to_slot[lastirq] = slot;
+	irqstore[dev->bus->number][slot] = lastirq;
+	lastirq++;
+	return lastirq - 1;
+}
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+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)
+{
+	pci_fixup_irqs(pci_swizzle, pci_map_irq);
+}
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+                          struct pbus_set_ranges_data * ranges)
+{
+	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;
+}
+
+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)
+{
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
+
+char * __init
+pcibios_setup(char *str)
+{
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+/*
+ * Device might live on a subordinate PCI bus.  XXX Walk up the chain of buses
+ * to find the slot number in sense of the bridge device register.
+ * XXX This also means multiple devices might rely on conflicting bridge
+ * settings.
+ */
+
+static void __init
+pci_disable_swapping(struct pci_dev *dev)
+{
+	unsigned int bus_id = (unsigned) dev->bus->number;
+	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
+	                                               bus_to_wid[bus_id]);
+	int		slot = PCI_SLOT(dev->devfn);
+
+	/* Turn off byte swapping */
+	bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
+	bridge->b_widget.w_tflush;		/* Flush */
+}
+
+static void __init
+pci_enable_swapping(struct pci_dev *dev)
+{
+	unsigned int bus_id = (unsigned) dev->bus->number;
+	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
+	                                               bus_to_wid[bus_id]);
+	int		slot = PCI_SLOT(dev->devfn);
+
+	/* Turn on byte swapping */
+	bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+	bridge->b_widget.w_tflush;		/* Flush */
+}
+
+static void __init
+pci_fixup_ioc3(struct pci_dev *d)
+{
+	unsigned long bus_id = (unsigned) d->bus->number;
+
+	printk("PCI: Fixing base addresses for IOC3 device %s\n", d->slot_name);
+
+	d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]);
+	d->resource[0].end   |= NODE_OFFSET(bus_to_nid[bus_id]);
+
+	pci_disable_swapping(d);
+}
+
+static void __init
+pci_fixup_isp1020(struct pci_dev *d)
+{
+	unsigned short command;
+
+	d->resource[0].start |= ((unsigned long)(bus_to_nid[d->bus->number])<<32);
+	printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name);
+
+	/*
+	 * Configure device to allow bus mastering, i/o and memory mapping.
+	 * Older qlogicisp driver expects to have the IO space enable
+	 * bit set. Things stop working if we program the controllers as not
+	 * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
+	 */
+
+	pci_set_master(d);
+	pci_read_config_word(d, PCI_COMMAND, &command);
+	command |= PCI_COMMAND_MEMORY;
+	command |= PCI_COMMAND_IO;
+	pci_write_config_word(d, PCI_COMMAND, command);
+	d->resource[1].flags |= 1;
+
+	pci_enable_swapping(d);
+}
+
+static void __init
+pci_fixup_isp2x00(struct pci_dev *d)
+{
+	unsigned int bus_id = (unsigned) d->bus->number;
+	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
+				     bus_to_wid[bus_id]);
+	bridgereg_t 	devreg;
+	int		i;
+	int		slot = PCI_SLOT(d->devfn);
+	unsigned int	start;
+	unsigned short command;
+
+	printk("PCI: Fixing isp2x00 in [bus:slot.fn] %s\n", d->slot_name);
+
+	/* set the resource struct for this device */
+	start = (u32) (u64)bridge;	/* yes, we want to lose the upper 32 bits here */
+	start |= BRIDGE_DEVIO(slot);
+
+	d->resource[0].start = start;
+	d->resource[0].end = d->resource[0].start + 0xff;
+	d->resource[0].flags = IORESOURCE_IO;
+
+	d->resource[1].start = start;
+	d->resource[1].end = d->resource[0].start + 0xfff;
+	d->resource[1].flags = IORESOURCE_MEM;
+
+	/*
+	 * set the bridge device(x) reg for this device
+	 */
+	devreg = bridge->b_device[slot].reg;
+	/* point device(x) to it appropriate small window */
+	devreg &= ~BRIDGE_DEV_OFF_MASK;
+	devreg |= (start >> 20) & BRIDGE_DEV_OFF_MASK;
+	bridge->b_device[slot].reg = devreg;
+
+	pci_enable_swapping(d);
+
+	/* set card's base addr reg */
+	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x500001);
+	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0x8b00000);
+	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, 0x8b20000);
+
+	/* I got these from booting irix on system...*/
+	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x200001);
+	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0xf800000);
+	pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS,   0x10200000);
+
+	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, start);
+	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, (start | 0x20000));
+
+	/* set cache line size */
+	pci_conf0_write_config_dword(d, PCI_CACHE_LINE_SIZE, 0xf080);
+
+	/* set pci bus timeout */
+	bridge->b_bus_timeout |= BRIDGE_BUS_PCI_RETRY_HLD(0x3);
+	bridge->b_wid_tflush;
+	printk("PCI: bridge bus timeout= 0x%x \n", bridge->b_bus_timeout);
+
+	/* set host error field */
+	bridge->b_int_host_err = 0x44;
+	bridge->b_wid_tflush;
+
+	bridge->b_wid_tflush;   	/* wait until Bridge PIO complete */
+	for (i=0; i<8; i++)
+		printk("PCI: device(%d)= 0x%x\n",i,bridge->b_device[i].reg);
+
+	/* configure device to allow bus mastering, i/o and memory mapping */
+	pci_set_master(d);
+	pci_read_config_word(d, PCI_COMMAND, &command);
+	command |= PCI_COMMAND_MEMORY;
+	command |= PCI_COMMAND_IO;
+	pci_write_config_word(d, PCI_COMMAND, command);
+	/*d->resource[1].flags |= 1;*/
+}
+
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+	  pci_fixup_ioc3 },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
+	  pci_fixup_isp1020 },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
+	  pci_fixup_isp2x00 },
+	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
+	  pci_fixup_isp2x00 },
+	{ 0 }
+};
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-reset.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-reset.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-reset.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-reset.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,80 @@
+/*
+ * This file is subject to 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 IP27.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#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>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/sn0/hub.h>
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+#define noreturn while(1);				/* Silence gcc.  */
+
+/* XXX How to pass the reboot command to the firmware??? */
+static void ip27_machine_restart(char *command)
+{
+#if 0
+	int i;
+#endif
+
+	printk("Reboot started from CPU %d\n", smp_processor_id());
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+#if 0
+	for (i = 0; i < numnodes; i++)
+		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+							PROMOP_REBOOT);
+#else
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+#endif
+	noreturn;
+}
+
+static void ip27_machine_halt(void)
+{
+	int i;
+
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	for (i = 0; i < numnodes; i++)
+		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+							PROMOP_RESTART);
+	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+	noreturn;
+}
+
+static void ip27_machine_power_off(void)
+{
+	/* To do ...  */
+	noreturn;
+}
+
+void ip27_reboot_setup(void)
+{
+	_machine_restart = ip27_machine_restart;
+	_machine_halt = ip27_machine_halt;
+	_machine_power_off = ip27_machine_power_off;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-rtc.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-rtc.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-rtc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-rtc.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,334 @@
+/*
+ *	Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
+ *
+ *	Real Time Clock interface for Linux
+ *
+ *	TODO: Implement periodic interrupts.
+ *
+ *	Copyright (C) 2000 Silicon Graphics, Inc.
+ *	Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ *
+ *	Based on code written by Paul Gortmaker.
+ *
+ *	This driver allows use of the real time clock (built into
+ *	nearly all computers) from user space. It exports the /dev/rtc
+ *	interface supporting various ioctl() and also the /proc/rtc
+ *	pseudo-file for status 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.
+ *
+ */
+
+#define RTC_VERSION		"1.09b"
+
+#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/rtc.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+
+#include <asm/m48t35.h>
+#include <asm/sn/ioc3.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+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);
+
+static void get_rtc_time(struct rtc_time *rtc_tm);
+
+/*
+ *	Bits in rtc_status. (6 bits of room for future expansion)
+ */
+
+#define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
+#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;
+
+/*
+ *	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 = 1970;	/* year corresponding to 0x00	*/
+
+static const unsigned char days_in_mo[] =
+{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+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	*/
+	{
+		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;
+		unsigned long flags;
+
+		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 + 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 -= epoch) > 255)    /* They are unsigned */
+			return -EINVAL;
+
+		save_flags(flags);
+		cli();
+		if (yrs > 169) {
+			restore_flags(flags);
+			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);
+
+		rtc->control &= ~M48T35_RTC_SET;
+		rtc->year = yrs;
+		rtc->month = mon;
+		rtc->date = day;
+		rtc->hour = hrs;
+		rtc->min = min;
+		rtc->sec = sec;
+		rtc->control &= ~M48T35_RTC_SET;
+
+		restore_flags(flags);
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	}
+	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
+}
+
+/*
+ *	We enforce only one user at a time here with the open/close.
+ *	Also clear the previous interrupt data on an open, and clean
+ *	up things on a close.
+ */
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	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;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	/*
+	 * Turn off all interrupts once the device is no longer
+	 * in use, and clear the data.
+	 */
+
+	spin_lock(rtc_status_lock);
+	rtc_status &= ~RTC_IS_OPEN;
+	spin_unlock(rtc_status_lock);
+
+	return 0;
+}
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+	owner:		THIS_MODULE,
+	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)
+{
+	unsigned long flags;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)
+	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
+
+	printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
+	if (misc_register(&rtc_dev))
+		return -ENODEV;
+	create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
+
+	save_flags(flags);
+	cli();
+	restore_flags(flags);
+	rtc_freq = 1024;
+	return 0;
+}
+
+static void __exit rtc_exit (void)
+{
+	/* interrupts and timer disabled at this point by rtc_release */
+
+	remove_proc_entry ("rtc", NULL);
+	misc_deregister(&rtc_dev);
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
+EXPORT_NO_SYMBOLS;
+
+/*
+ *	Info exported via "/proc/rtc".
+ */
+
+static int rtc_get_status(char *buf)
+{
+	char *p;
+	struct rtc_time tm;
+
+	/*
+	 * Just emulate the standard /proc/rtc
+	 */
+
+	p = buf;
+
+	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"
+		     "24hr\t\t: yes\n",
+		     tm.tm_hour, tm.tm_min, tm.tm_sec,
+		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
+
+	return  p - buf;
+}
+
+static int rtc_read_proc(char *page, char **start, off_t off,
+                                 int count, int *eof, void *data)
+{
+        int len = rtc_get_status(page);
+        if (len <= off+count) *eof = 1;
+        *start = page + off;
+        len -= off;
+        if (len>count) len = count;
+        if (len<0) len = 0;
+        return len;
+}
+
+static void get_rtc_time(struct rtc_time *rtc_tm)
+{
+
+	unsigned long flags;
+
+	/*
+	 * Do we need to wait for the last update to finish?
+	 */
+
+	/*
+	 * Only the values that we read from the RTC are set. We leave
+	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
+	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
+	 * by the RTC when initially set to a non-zero value.
+	 */
+	save_flags(flags);
+	cli();
+        rtc->control |= M48T35_RTC_READ;
+	rtc_tm->tm_sec = rtc->sec;
+	rtc_tm->tm_min = rtc->min;
+	rtc_tm->tm_hour = rtc->hour;
+	rtc_tm->tm_mday = rtc->date;
+	rtc_tm->tm_mon = rtc->month;
+	rtc_tm->tm_year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+	restore_flags(flags);
+
+	BCD_TO_BIN(rtc_tm->tm_sec);
+	BCD_TO_BIN(rtc_tm->tm_min);
+	BCD_TO_BIN(rtc_tm->tm_hour);
+	BCD_TO_BIN(rtc_tm->tm_mday);
+	BCD_TO_BIN(rtc_tm->tm_mon);
+	BCD_TO_BIN(rtc_tm->tm_year);
+
+	/*
+	 * Account for differences between how the RTC uses the values
+	 * and how they are defined in a struct rtc_time;
+	 */
+	if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
+		rtc_tm->tm_year += 100;
+
+	rtc_tm->tm_mon--;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-setup.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-setup.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,314 @@
+/*
+ * This file is subject to 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 IP27 specific setup.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#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>
+#include <asm/sn/sn0/hubni.h>
+#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>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+#include <asm/sn/sn0/ip27.h>
+
+/* Check against user dumbness.  */
+#ifdef CONFIG_VT
+#error CONFIG_VT not allowed for IP27.
+#endif
+
+#undef DEBUG_SETUP
+#ifdef DEBUG_SETUP
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/*
+ * get_nasid() returns the physical node id number of the caller.
+ */
+nasid_t
+get_nasid(void)
+{
+	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
+	                 >> NSRI_NODEID_SHFT);
+}
+
+/* Extracted from the IOC3 meta driver.  FIXME.  */
+static inline void ioc3_sio_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+        long loops;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */
+	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */
+	ioc3->sio_iec = ~0;
+	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
+
+	loops=1000000; while(loops--);
+	ioc3->sregs.uarta.iu_fcr = 0;
+	ioc3->sregs.uartb.iu_fcr = 0;
+	loops=1000000; while(loops--);
+}
+
+static inline void ioc3_eth_init(void)
+{
+	struct ioc3 *ioc3;
+	nasid_t nid;
+
+	nid = get_nasid();
+	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+	ioc3->eier = 0;
+}
+
+/* Try to catch kernel missconfigurations and give user an indication what
+   option to select.  */
+static void __init verify_mode(void)
+{
+	int n_mode;
+
+	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
+	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
+#ifdef CONFIG_SGI_SN0_N_MODE
+	if (!n_mode)
+		panic("Kernel compiled for M mode.");
+#else
+	if (n_mode)
+		panic("Kernel compiled for N mode.");
+#endif
+}
+
+#define XBOW_WIDGET_PART_NUM    0x0
+#define XXBOW_WIDGET_PART_NUM   0xd000          /* Xbridge */
+#define BASE_XBOW_PORT  	8     /* Lowest external port */
+
+unsigned int bus_to_cpu[256];
+unsigned long bus_to_baddr[256];
+
+void __init pcibr_setup(cnodeid_t nid)
+{
+	int 			i, start, num;
+	unsigned long		masterwid;
+	bridge_t 		*bridge;
+	volatile u64 		hubreg;
+	nasid_t	 		nasid, masternasid;
+	xwidget_part_num_t	partnum;
+	widgetreg_t 		widget_id;
+	static spinlock_t	pcibr_setup_lock = SPIN_LOCK_UNLOCKED;
+
+	/*
+	 * If the master is doing this for headless node, nothing to do.
+	 * This is because currently we require at least one of the hubs
+	 * (master hub) connected to the xbow to have at least one enabled
+	 * cpu to receive intrs. Else we need an array bus_to_intrnasid[]
+	 * that bridge_startup() needs to use to target intrs. All dma is
+	 * routed thru the widget of the master hub. The master hub wid
+	 * is selectable by WIDGET_A below.
+	 */
+	if (nid != get_compact_nodeid())
+		return;
+	/*
+	 * find what's on our local node
+	 */
+	spin_lock(&pcibr_setup_lock);
+	start = num_bridges;		/* Remember where we start from */
+	nasid = COMPACT_TO_NASID_NODEID(nid);
+	hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+	if (hubreg & IIO_LLP_CSR_IS_UP) {
+		/* link is up */
+		widget_id = *(volatile widgetreg_t *)
+                        (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
+		partnum = XWIDGET_PART_NUM(widget_id);
+		printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
+					smp_processor_id(), nasid, partnum);
+		if (partnum == BRIDGE_WIDGET_PART_NUM) {
+			/*
+			 * found direct connected bridge so must be Origin200
+			 */
+			printk("...is bridge\n");
+			num_bridges = 1;
+        		bus_to_wid[0] = 0x8;
+			bus_to_nid[0] = 0;
+			masterwid = 0xa;
+			bus_to_baddr[0] = 0xa100000000000000UL;
+		} else if (partnum == XBOW_WIDGET_PART_NUM) {
+			lboard_t *brd;
+			klxbow_t *xbow_p;
+			/*
+			 * found xbow, so may have multiple bridges
+			 * need to probe xbow
+			 */
+			printk("...is xbow\n");
+
+			if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
+                                   KLTYPE_MIDPLANE8)) == NULL)
+				printk("argh\n");
+			else
+				printk("brd = 0x%lx\n", (unsigned long) brd);
+			if ((xbow_p = (klxbow_t *)
+			     find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
+				printk("argh\n");
+			else {
+			   /*
+			    * Okay, here's a xbow. Lets arbitrate and find
+			    * out if we should initialize it. Set enabled
+			    * hub connected at highest or lowest widget as
+			    * master.
+			    */
+#ifdef WIDGET_A
+			   i = HUB_WIDGET_ID_MAX + 1;
+			   do {
+				i--;
+			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#else
+			   i = HUB_WIDGET_ID_MIN - 1;
+			   do {
+				i++;
+			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#endif
+			   masterwid = i;
+			   masternasid = XBOW_PORT_NASID(xbow_p, i);
+			   if (nasid == masternasid)
+			   for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
+				if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
+					continue;
+				if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
+				   widget_id = *(volatile widgetreg_t *)
+                        		   (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
+				   partnum = XWIDGET_PART_NUM(widget_id);
+				   if (partnum == BRIDGE_WIDGET_PART_NUM) {
+					printk("widget 0x%x is a bridge\n", i);
+					bus_to_wid[num_bridges] = i;
+					bus_to_nid[num_bridges] = nasid;
+					bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56));	/* Barrier set */
+					num_bridges++;
+				   }
+				}
+			   }
+			}
+		} else if (partnum == XXBOW_WIDGET_PART_NUM) {
+			/*
+			 * found xbridge, assume ibrick for now
+			 */
+			printk("...is xbridge\n");
+        		bus_to_wid[0] = 0xb;
+        		bus_to_wid[1] = 0xe;
+        		bus_to_wid[2] = 0xf;
+
+        		bus_to_nid[0] = 0;
+        		bus_to_nid[1] = 0;
+        		bus_to_nid[2] = 0;
+
+			bus_to_baddr[0] = 0xa100000000000000UL;
+			bus_to_baddr[1] = 0xa100000000000000UL;
+			bus_to_baddr[2] = 0xa100000000000000UL;
+			masterwid = 0xa;
+			num_bridges = 3;
+		}
+	}
+	num = num_bridges - start;
+	spin_unlock(&pcibr_setup_lock);
+	/*
+         * set bridge registers
+         */
+	for (i = start; i < (start + num); i++) {
+
+		DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %d\n",
+                        i, i, bus_to_wid[i], i, bus_to_nid[i]);
+
+		bus_to_cpu[i] = smp_processor_id();
+		/*
+		 * point to this bridge
+		 */
+		bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
+		/*
+	 	 * Clear all pending interrupts.
+	 	 */
+		bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
+		/*
+	 	 * Until otherwise set up, assume all interrupts are from slot 0
+	 	 */
+		bridge->b_int_device = (u32) 0x0;
+		/*
+	 	 * swap pio's to pci mem and io space (big windows)
+	 	 */
+		bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
+		bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
+
+		/*
+		 * Hmm...  IRIX sets additional bits in the address which
+		 * are documented as reserved in the bridge docs.
+		 */
+		bridge->b_int_mode = 0x0;		/* Don't clear ints */
+		bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
+		bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/
+		bridge->b_dir_map = (masterwid << 20);	/* DMA */
+		bridge->b_int_enable = 0;
+
+		bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
+	}
+}
+
+extern void ip27_setup_console(void);
+extern void ip27_time_init(void);
+
+void __init ip27_setup(void)
+{
+	nasid_t nid;
+	hubreg_t p, e;
+
+	ip27_setup_console();
+
+	num_bridges = 0;
+	/*
+	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
+	 */
+	DBG("ip27_setup(): Entered.\n");
+	nid = get_nasid();
+	printk("IP27: Running on node %d.\n", nid);
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
+	printk("Node %d has %s primary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
+	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
+	printk("Node %d has %s secondary CPU%s.\n", nid,
+	       p ? "a" : "no",
+	       e ? ", CPU is running" : "");
+
+	verify_mode();
+	ioc3_sio_init();
+	ioc3_eth_init();
+	per_cpu_init();
+
+	mips_io_port_base = IO_BASE;
+	board_time_init = ip27_time_init;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-timer.c linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-timer.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip27/ip27-timer.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-timer.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,239 @@
+/*
+ * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#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>
+#include <asm/m48t35.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * 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.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE		800
+#define NSEC_PER_SEC		1000000000
+#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
+#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
+
+static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
+static long last_rtc_update;		/* Last time the rtc clock got updated */
+
+extern rwlock_t xtime_lock;
+extern volatile unsigned long wall_jiffies;
+
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+							IOC3_BYTEBUS_DEV0);
+
+	rtc->control |= M48T35_RTC_READ;
+	cmos_minutes = rtc->min;
+	BCD_TO_BIN(cmos_minutes);
+	rtc->control &= ~M48T35_RTC_READ;
+
+	/*
+	 * 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) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		rtc->control |= M48T35_RTC_SET;
+		rtc->sec = real_seconds;
+		rtc->min = real_minutes;
+		rtc->control &= ~M48T35_RTC_SET;
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	return retval;
+}
+
+void rt_timer_interrupt(struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	int cpuA = ((cputoslice(cpu)) == 0);
+	int irq = 9;				/* XXX Assign number */
+
+	irq_enter(cpu, irq);
+	write_lock(&xtime_lock);
+
+again:
+	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
+	ct_cur[cpu] += CYCLES_PER_JIFFY;
+	LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
+
+	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
+		goto again;
+
+	kstat.irqs[cpu][irq]++;		/* kstat only for bootcpu? */
+
+	if (cpu == 0)
+		do_timer(regs);
+
+#ifdef CONFIG_SMP
+	update_process_times(user_mode(regs));
+#endif /* CONFIG_SMP */
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to when a second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660) {
+		if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
+			if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
+				last_rtc_update = xtime.tv_sec;
+			else
+				last_rtc_update = xtime.tv_sec - 600;
+		} else if (xtime.tv_usec <= ((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;
+		}
+        }
+
+	write_unlock(&xtime_lock);
+	irq_exit(cpu, irq);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+}
+
+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;
+}
+
+/* Includes for ioc3_init().  */
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/pci/bridge.h>
+
+static __init unsigned long get_m48t35_time(void)
+{
+        unsigned int year, month, date, hour, min, sec;
+	struct m48t35_rtc *rtc;
+	nasid_t nid;
+
+	nid = get_nasid();
+	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
+							IOC3_BYTEBUS_DEV0);
+
+	rtc->control |= M48T35_RTC_READ;
+	sec = rtc->sec;
+	min = rtc->min;
+	hour = rtc->hour;
+	date = rtc->date;
+	month = rtc->month;
+	year = rtc->year;
+	rtc->control &= ~M48T35_RTC_READ;
+
+        BCD_TO_BIN(sec);
+        BCD_TO_BIN(min);
+        BCD_TO_BIN(hour);
+        BCD_TO_BIN(date);
+        BCD_TO_BIN(month);
+        BCD_TO_BIN(year);
+
+        year += 1970;
+
+        return mktime(year, month, date, hour, min, sec);
+}
+
+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)
+{
+	lboard_t *board;
+	klcpu_t *cpu;
+	int cpuid;
+
+	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
+	board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
+	if (!board)
+		panic("Can't find board info for myself.");
+
+	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
+	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
+	if (!cpu)
+		panic("No information about myself?");
+
+	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
+
+	set_cp0_status(SRB_TIMOCLK);
+}
+
+void __init hub_rtc_init(cnodeid_t cnode)
+{
+	/*
+	 * We only need to initialize the current node.
+	 * If this is not the current node then it is a cpuless
+	 * node and timeouts will not happen there.
+	 */
+	if (get_compact_nodeid() == cnode) {
+		int cpu = smp_processor_id();
+		LOCAL_HUB_S(PI_RT_EN_A, 1);
+		LOCAL_HUB_S(PI_RT_EN_B, 1);
+		LOCAL_HUB_S(PI_PROF_EN_A, 0);
+		LOCAL_HUB_S(PI_PROF_EN_B, 0);
+		ct_cur[cpu] = CYCLES_PER_JIFFY;
+		LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
+		LOCAL_HUB_S(PI_RT_COUNT, 0);
+		LOCAL_HUB_S(PI_RT_PEND_A, 0);
+		LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
+		LOCAL_HUB_S(PI_RT_COUNT, 0);
+		LOCAL_HUB_S(PI_RT_PEND_B, 0);
+	}
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/Makefile linux-2.4.20-pre7/arch/mips/sgi-ip32/Makefile
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,22 @@
+#
+# 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 := ip32-kern.a
+
+all: ip32-kern.a ip32-irq-glue.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
+
+obj-$(CONFIG_PCI)   += ip32-pci.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/crime.c linux-2.4.20-pre7/arch/mips/sgi-ip32/crime.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/crime.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/crime.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to 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
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/ip32/crime.h>
+#include <asm/ptrace.h>
+
+void __init crime_init (void)
+{
+	u64 id = crime_read_64 (CRIME_ID);
+	u64 rev = id & CRIME_ID_REV;
+
+	id = (id & CRIME_ID_IDBITS) >> 4;
+
+	printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev,
+		(unsigned long) CRIME_BASE);
+}
+
+/* XXX Like on Sun, these give us various useful information to printk. */
+void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT);
+	u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR);
+	memerr &= CRIME_MEM_ERROR_STAT_MASK;
+
+	printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n",
+		addr << 2, memerr);
+
+	crime_write_64 (CRIME_MEM_ERROR_STAT, 0);
+}
+
+void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT);
+	u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR);
+	cpuerr &= CRIME_CPU_ERROR_MASK;
+	addr <<= 2UL;
+
+	printk ("CRIME CPU interface error detected at %09lx status %08lx\n",
+		addr, cpuerr);
+
+	crime_write_64 (CRIME_CPU_ERROR_STAT, 0);
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-berr.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-berr.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-berr.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-berr.c	Thu Sep 12 20:01:40 2002
@@ -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) 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/addrspace.h>
+#include <asm/ptrace.h>
+
+int
+be_ip32_handler(struct pt_regs *regs, int is_fixup)
+{
+	int data = regs->cp0_cause & 4;
+
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+
+	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
+	show_regs(regs);
+	dump_tlb_all();
+	while(1);
+	force_sig(SIGBUS, current);
+}
+
+void __init
+bus_error_init(void)
+{
+	be_board_handler = be_ip32_handler;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-irq-glue.S linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-irq-glue.S
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-irq-glue.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-irq-glue.S	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,87 @@
+/*
+ * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
+ *
+ * This file is subject to 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
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+#include <asm/ip32/ip32_ints.h>
+
+		.text
+		.set    noreorder
+		.set    noat
+		.align  5
+		NESTED(ip32_handle_int, PT_SIZE, ra)
+		.set    noat
+		SAVE_ALL
+		CLI			# TEST: interrupts should be off
+		.set    at
+		.set    noreorder
+
+		mfc0	s0,CP0_CAUSE
+
+		andi	t1, s0, IE_IRQ0
+		bnez	t1, handle_irq0
+		 andi	t1, s0, IE_IRQ1
+		bnez	t1, handle_irq1
+		 andi	t1, s0, IE_IRQ2
+		bnez	t1, handle_irq2
+		 andi	t1, s0, IE_IRQ3
+		bnez	t1, handle_irq3
+		 andi	t1, s0, IE_IRQ4
+		bnez	t1, handle_irq4
+		 andi	t1, s0, IE_IRQ5
+		bnez	t1, handle_irq5
+		 nop
+
+		/* Either someone has triggered the "software interrupts"
+		 * or we lost an interrupt somehow.  Ignore it.
+		 */
+		j	ret_from_irq
+		 nop
+
+handle_irq0:
+		jal	ip32_irq0
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq1:
+		jal	ip32_irq1
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq2:
+		jal	ip32_irq2
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq3:
+		jal	ip32_irq3
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq4:
+		jal	ip32_irq4
+		 move	a0, sp
+		j	ret_from_irq
+		 nop
+
+handle_irq5:
+		jal	ip32_irq5
+		move	a0, sp
+		j	ret_from_irq
+		 nop
+
+		END(ip32_handle_int)
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-irq.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-irq.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-irq.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,584 @@
+/*
+ * Code to handle IP32 IRQs
+ *
+ * This file is subject to 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
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/types.h>
+#include <linux/interrupt.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>
+#include <asm/system.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/signal.h>
+
+#undef DEBUG_IRQ
+#ifdef DEBUG_IRQ
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* O2 irq map
+ *
+ * IP0 -> software (ignored)
+ * IP1 -> software (ignored)
+ * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
+ * IP3 -> (irq1) X unknown
+ * IP4 -> (irq2) X unknown
+ * IP5 -> (irq3) X unknown
+ * IP6 -> (irq4) X unknown
+ * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
+ *
+ * crime: (C)
+ *
+ * CRIME_INT_STAT 31:0:
+ *
+ * 0 -> 1 Video in 1
+ * 1 -> 2 Video in 2
+ * 2 -> 3 Video out
+ * 3 -> 4 Mace ethernet
+ * 4 -> S  SuperIO sub-interrupt
+ * 5 -> M  Miscellaneous sub-interrupt
+ * 6 -> A  Audio sub-interrupt
+ * 7 -> 8  PCI bridge errors
+ * 8 -> 9  PCI SCSI aic7xxx 0
+ * 9 -> 10  PCI SCSI aic7xxx 1
+ * 10 -> 11 PCI slot 0
+ * 11 -> 12 unused (PCI slot 1)
+ * 12 -> 13 unused (PCI slot 2)
+ * 13 -> 14 unused (PCI shared 0)
+ * 14 -> 15 unused (PCI shared 1)
+ * 15 -> 16 unused (PCI shared 2)
+ * 16 -> 17 GBE0 (E)
+ * 17 -> 18 GBE1 (E)
+ * 18 -> 19 GBE2 (E)
+ * 19 -> 20 GBE3 (E)
+ * 20 -> 21 CPU errors
+ * 21 -> 22 Memory errors
+ * 22 -> 23 RE empty edge (E)
+ * 23 -> 24 RE full edge (E)
+ * 24 -> 25 RE idle edge (E)
+ * 25 -> 26 RE empty level
+ * 26 -> 27 RE full level
+ * 27 -> 28 RE idle level
+ * 28 -> 29  unused (software 0) (E)
+ * 29 -> 30  unused (software 1) (E)
+ * 30 -> 31  unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 32 VICE
+ *
+ * S, M, A: Use the MACE ISA interrupt register
+ * MACE_ISA_INT_STAT 31:0
+ *
+ * 0-7 -> 33-40 Audio
+ * 8 -> 41 RTC
+ * 9 -> 42 Keyboard
+ * 10 -> X Keyboard polled
+ * 11 -> 44 Mouse
+ * 12 -> X Mouse polled
+ * 13-15 -> 46-48 Count/compare timers
+ * 16-19 -> 49-52 Parallel (16 E)
+ * 20-25 -> 53-58 Serial 1 (22 E)
+ * 26-31 -> 59-64 Serial 2 (28 E)
+ *
+ * Note that this means IRQs 5-7, 43, and 45 do not exist.  This is a
+ * different IRQ map than IRIX uses, but that's OK as Linux irq handling
+ * is quite different anyway.
+ */
+
+/* Some initial interrupts to set up */
+extern void crime_memerr_intr (unsigned int irq, void *dev_id,
+			       struct pt_regs *regs);
+extern void crime_cpuerr_intr (unsigned int irq, void *dev_id,
+			       struct pt_regs *regs);
+
+struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
+			       0, "CRIME memory error", NULL,
+			       NULL };
+struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
+			       0, "CRIME CPU error", NULL,
+			       NULL };
+
+extern void ip32_handle_int (void);
+asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+/*
+ * 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)
+{
+	set_cp0_status(STATUSF_IP7);
+}
+
+static unsigned int startup_cpu_irq(unsigned int irq)
+{
+	enable_cpu_irq(irq);
+	return 0;
+}
+
+static void disable_cpu_irq(unsigned int irq)
+{
+	clear_cp0_status(STATUSF_IP7);
+}
+
+static void end_cpu_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_cpu_irq (irq);
+}
+
+#define shutdown_cpu_irq disable_cpu_irq
+#define mask_and_ack_cpu_irq disable_cpu_irq
+
+static struct hw_interrupt_type ip32_cpu_interrupt = {
+	"IP32 CPU",
+	startup_cpu_irq,
+	shutdown_cpu_irq,
+	enable_cpu_irq,
+	disable_cpu_irq,
+	mask_and_ack_cpu_irq,
+	end_cpu_irq,
+	NULL
+};
+
+/*
+ * This is for pure CRIME interrupts - ie not MACE.  The advantage?
+ * We get to split the register in half and do faster lookups.
+ */
+
+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);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
+}
+
+static unsigned int startup_crime_irq(unsigned int 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)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	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);
+}
+
+static void mask_and_ack_crime_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	/* Edge triggered interrupts must be cleared. */
+	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);
+		crime_mask &= ~(1 << (irq - 1));
+		crime_write_64(CRIME_HARD_INT, crime_mask);
+		restore_flags(flags);
+	}
+	disable_crime_irq(irq);
+}
+
+static void end_crime_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_crime_irq (irq);
+}
+
+#define shutdown_crime_irq disable_crime_irq
+
+static struct hw_interrupt_type ip32_crime_interrupt = {
+	"IP32 CRIME",
+	startup_crime_irq,
+	shutdown_crime_irq,
+	enable_crime_irq,
+	disable_crime_irq,
+	mask_and_ack_crime_irq,
+	end_crime_irq,
+	NULL
+};
+
+/*
+ * 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)
+{
+	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;
+	 * however, we never disable interrupts at that level.
+	 */
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_mask |= 1 << (irq - 1);
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags(flags);
+}
+
+static unsigned int startup_macepci_irq(unsigned int irq)
+{
+	enable_macepci_irq (irq);
+
+	return 0; /* XXX */
+}
+
+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);
+}
+
+static void end_macepci_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_macepci_irq (irq);
+}
+
+#define shutdown_macepci_irq disable_macepci_irq
+#define mask_and_ack_macepci_irq disable_macepci_irq
+
+static struct hw_interrupt_type ip32_macepci_interrupt = {
+	"IP32 MACE PCI",
+	startup_macepci_irq,
+	shutdown_macepci_irq,
+	enable_macepci_irq,
+	disable_macepci_irq,
+	mask_and_ack_macepci_irq,
+	end_macepci_irq,
+	NULL
+};
+
+/* This is used for MACE ISA interrupts.  That means bits 4-6 in the
+ * CRIME register.
+ */
+
+static void enable_maceisa_irq (unsigned int irq)
+{
+	u64 crime_mask;
+	u32 mace_mask;
+	unsigned int crime_int = 0;
+	unsigned long flags;
+
+	DBG ("maceisa enable: %u\n", irq);
+
+	switch (irq) {
+	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
+		crime_int = MACE_AUDIO_INT;
+		break;
+	case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
+		crime_int = MACE_MISC_INT;
+		break;
+	case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
+		crime_int = MACE_SUPERIO_INT;
+		break;
+	}
+	DBG ("crime_int %016lx enabled\n", crime_int);
+	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);
+	mace_mask |= 1 << (irq - 33);
+	mace_write_32(MACEISA_INT_MASK, mace_mask);
+	restore_flags(flags);
+}
+
+static unsigned int startup_maceisa_irq (unsigned int irq)
+{
+	enable_maceisa_irq(irq);
+	return 0;
+}
+
+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 &= ~(1 << (irq - 33));
+	mace_write_32(MACEISA_INT_MASK, mace_mask);
+	restore_flags(flags);
+}
+
+static void mask_and_ack_maceisa_irq(unsigned int irq)
+{
+	u32 mace_mask;
+	unsigned long flags;
+
+	switch (irq) {
+	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);
+		mace_mask &= ~(1 << (irq - 33));
+		mace_write_32(MACEISA_INT_STAT, mace_mask);
+		restore_flags(flags);
+		break;
+	}
+	disable_maceisa_irq(irq);
+}
+
+static void end_maceisa_irq(unsigned irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_maceisa_irq (irq);
+}
+
+#define shutdown_maceisa_irq disable_maceisa_irq
+
+static struct hw_interrupt_type ip32_maceisa_interrupt = {
+	"IP32 MACE ISA",
+	startup_maceisa_irq,
+	shutdown_maceisa_irq,
+	enable_maceisa_irq,
+	disable_maceisa_irq,
+	mask_and_ack_maceisa_irq,
+	end_maceisa_irq,
+	NULL
+};
+
+/* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
+ * bits 0-3 and 7 in the CRIME register.
+ */
+
+static void enable_mace_irq(unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	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);
+}
+
+static unsigned int startup_mace_irq(unsigned int irq)
+{
+	enable_mace_irq(irq);
+	return 0;
+}
+
+static void disable_mace_irq(unsigned int irq)
+{
+	u64 crime_mask;
+	unsigned long flags;
+
+	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);
+}
+
+static void end_mace_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		enable_mace_irq (irq);
+}
+
+#define shutdown_mace_irq disable_mace_irq
+#define mask_and_ack_mace_irq disable_mace_irq
+
+static struct hw_interrupt_type ip32_mace_interrupt = {
+	"IP32 MACE",
+	startup_mace_irq,
+	shutdown_mace_irq,
+	enable_mace_irq,
+	disable_mace_irq,
+	mask_and_ack_mace_irq,
+	end_mace_irq,
+	NULL
+};
+
+static void ip32_unknown_interrupt (struct pt_regs *regs)
+{
+	u64 crime;
+	u32 mace;
+
+	printk ("Unknown interrupt occurred!\n");
+	printk ("cp0_status: %08x\tcp0_cause: %08x\n",
+		read_32bit_cp0_register (CP0_STATUS),
+		read_32bit_cp0_register (CP0_CAUSE));
+	crime = crime_read_64 (CRIME_INT_MASK);
+	printk ("CRIME interrupt mask: %016lx\n", crime);
+	crime = crime_read_64 (CRIME_INT_STAT);
+	printk ("CRIME interrupt status: %016lx\n", crime);
+	crime = crime_read_64 (CRIME_HARD_INT);
+	printk ("CRIME hardware interrupt register: %016lx\n", crime);
+	mace = mace_read_32 (MACEISA_INT_MASK);
+	printk ("MACE ISA interrupt mask: %08x\n", mace);
+	mace = mace_read_32 (MACEISA_INT_STAT);
+	printk ("MACE ISA interrupt status: %08x\n", mace);
+	mace = mace_read_32 (MACEPCI_CONTROL);
+	printk ("MACE PCI control register: %08x\n", mace);
+
+	printk("Register dump:\n");
+	show_regs(regs);
+
+	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)
+{
+	u64 crime_int;
+	u64 crime_mask;
+	int irq = 0;
+	unsigned long flags;
+
+	save_and_cli (flags);
+	/* disable crime interrupts */
+	crime_mask = crime_read_64(CRIME_INT_MASK);
+	crime_write_64(CRIME_INT_MASK, 0);
+
+	crime_int = crime_read_64(CRIME_INT_STAT);
+
+	if (crime_int & CRIME_MACE_INT_MASK) {
+		crime_int &= CRIME_MACE_INT_MASK;
+		irq = ffs (crime_int);
+	} else if (crime_int & CRIME_MACEISA_INT_MASK) {
+		u32 mace_int;
+		mace_int = mace_read_32 (MACEISA_INT_STAT);
+		if (mace_int == 0)
+			irq = 0;
+		else
+			irq = ffs (mace_int) + 32;
+	} else if (crime_int & CRIME_MACEPCI_INT_MASK) {
+		crime_int &= CRIME_MACEPCI_INT_MASK;
+		crime_int >>= 8;
+		irq = ffs (crime_int) + 8;
+	} else if (crime_int & 0xffff0000) {
+		crime_int >>= 16;
+		irq = ffs (crime_int) + 16;
+	}
+	if (irq == 0)
+		ip32_unknown_interrupt(regs);
+	DBG("*irq %u*\n", irq);
+	do_IRQ(irq, regs);
+
+	/* enable crime interrupts */
+	crime_write_64(CRIME_INT_MASK, crime_mask);
+	restore_flags (flags);
+}
+
+void ip32_irq1(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq2(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq3(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (regs);
+}
+
+void ip32_irq4(struct pt_regs *regs)
+{
+	ip32_unknown_interrupt (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 -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-pci.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-pci.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-pci.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-pci.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,460 @@
+/*
+ * This file is subject to 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 Keith M Wesolowski
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+#include <linux/delay.h>
+
+#undef DEBUG_MACE_PCI
+
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
+ * map looks like this:
+ *
+ * 0  aic7xxx 0
+ * 1  aic7xxx 1
+ * 2  expansion slot
+ * 3  N/C
+ * 4  N/C
+ */
+
+#define chkslot(dev)							\
+do {									\
+	if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1	\
+	    || PCI_SLOT ((dev)->devfn) > 3)				\
+		return PCIBIOS_DEVICE_NOT_FOUND;			\
+} while (0)
+
+#define mkaddr(dev, where) \
+((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
+
+void macepci_error (int irq, void *dev, struct pt_regs *regs);
+
+static int macepci_read_config_byte (struct pci_dev *dev, int where,
+				     u8 *val)
+{
+	*val = 0xff;
+	chkslot (dev);
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_read_config_word (struct pci_dev *dev, int where,
+				     u16 *val)
+{
+	*val = 0xffff;
+	chkslot (dev);
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+ 	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_read_config_dword (struct pci_dev *dev, int where,
+				      u32 *val)
+{
+	*val = 0xffffffff;
+	chkslot (dev);
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	*val = mace_read_32 (MACEPCI_CONFIG_DATA);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_byte (struct pci_dev *dev, int where,
+				      u8 val)
+{
+	chkslot (dev);
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_word (struct pci_dev *dev, int where,
+				      u16 val)
+{
+	chkslot (dev);
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int macepci_write_config_dword (struct pci_dev *dev, int where,
+                                          u32 val)
+{
+	chkslot (dev);
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
+	mace_write_32 (MACEPCI_CONFIG_DATA, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops macepci_ops = {
+	macepci_read_config_byte,
+	macepci_read_config_word,
+	macepci_read_config_dword,
+	macepci_write_config_byte,
+	macepci_write_config_word,
+	macepci_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = { { 0 } };
+
+void __init pcibios_init (void)
+{
+	struct pci_dev *dev;
+	u32 start, size;
+	u16 cmd;
+	u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
+	u32 base_mem = 0x80100000; /* Likewise */
+	u32 rev = mace_read_32 (MACEPCI_REV);
+	int i;
+
+	printk ("MACE: PCI rev %d detected at %016lx\n", rev,
+		(u64) MACE_BASE + MACE_PCI);
+
+	/* These are *bus* addresses */
+	ioport_resource.start = 0;
+	ioport_resource.end = 0xffffffffUL;
+	iomem_resource.start = 0x80000000UL;
+	iomem_resource.end = 0xffffffffUL;
+
+	/* Clear any outstanding errors and enable interrupts */
+	mace_write_32 (MACEPCI_ERROR_ADDR, 0);
+	mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
+	mace_write_32 (MACEPCI_CONTROL, 0xff008500);
+	crime_write_64 (CRIME_HARD_INT, 0UL);
+	crime_write_64 (CRIME_SOFT_INT, 0UL);
+	crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
+
+	if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
+			 "MACE PCI error", NULL))
+		panic("PCI bridge can't get interrupt; can't happen.");
+
+	pci_scan_bus (0, &macepci_ops, NULL);
+
+#ifdef DEBUG_MACE_PCI
+	pci_for_each_dev (dev) {
+		printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
+			dev->bus->number, PCI_SLOT (dev->devfn),
+			PCI_FUNC (dev->devfn));
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			printk ("%d: %016lx - %016lx (flags %04lx)\n",
+				i, dev->resource[i].start,
+				dev->resource[i].end, dev->resource[i].flags);
+		}
+	}
+#endif
+	/*
+	 * Assign sane resources to and enable all devices.  The requirement
+	 * for the SCSI controllers is well-known: a 256-byte I/O region
+	 * which we must assign, and a 1-page memory region which is
+	 * assigned by the system firmware.
+	 */
+	pci_for_each_dev (dev) {
+		switch (PCI_SLOT (dev->devfn)) {
+		case 1: /* SCSI bus 0 */
+			dev->resource[0].start = 0x1000UL;
+			dev->resource[0].end = 0x10ffUL;
+			break;
+		case 2: /* SCSI bus 1 */
+			dev->resource[0].start = 0x2000UL;
+			dev->resource[0].end = 0x20ffUL;
+			break;
+		default: /* Slots - I guess we have only 1 */
+			for (i=0; i < 6; i++) {
+				size = dev->resource[i].end
+					- dev->resource[i].start;
+				if (!size
+				    || !(dev->resource[i].flags
+					 & (IORESOURCE_IO|IORESOURCE_MEM))) {
+					dev->resource[i].start
+						= dev->resource[i].end = 0UL;
+					continue;
+				}
+				if (dev->resource[i].flags & IORESOURCE_IO) {
+					dev->resource[i].start = base_io;
+					base_io += PAGE_ALIGN (size);
+				} else {
+					dev->resource[i].start = base_mem;
+					base_mem += 0x100000UL;
+				}
+				dev->resource[i].end =
+					dev->resource[i].start + size;
+			}
+			break;
+		}
+		for (i=0; i < 6; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			start = dev->resource[i].start;
+			if (dev->resource[i].flags & IORESOURCE_IO)
+				start |= 1;
+			pci_write_config_dword (dev,
+				PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
+		}
+		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_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);
+
+	pci_for_each_dev (dev) {
+		printk ("Device: %d/%d/%d final bus resource map\n",
+			dev->bus->number, PCI_SLOT (dev->devfn),
+			PCI_FUNC (dev->devfn));
+		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
+			if (dev->resource[i].start == 0)
+				continue;
+			printk ("%d: %016lx - %016lx (flags %04lx)\n",
+				i, dev->resource[i].start,
+				dev->resource[i].end, dev->resource[i].flags);
+		}
+	}
+#endif
+}
+
+/*
+ * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
+ * the device (1-4 => A-D), tell what irq to use.  Note that we don't
+ * in theory have slots 4 and 5, and we never normally use the shared
+ * irqs.  I suppose a device without a pin A will thank us for doing it
+ * right if there exists such a broken piece of crap.
+ */
+static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
+{
+	chkslot (dev);
+	if (pin == 0)
+		pin = 1;
+	switch (slot) {
+	case 1:
+		return MACEPCI_SCSI0_IRQ;
+	case 2:
+		return MACEPCI_SCSI1_IRQ;
+	case 3:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED0_IRQ;
+		case 3:
+			return MACEPCI_SHARED1_IRQ;
+		case 4:
+			return MACEPCI_SHARED2_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT0_IRQ;
+		}
+	case 4:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED2_IRQ;
+		case 3:
+			return MACEPCI_SHARED0_IRQ;
+		case 4:
+			return MACEPCI_SHARED1_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT1_IRQ;
+		}
+		return MACEPCI_SLOT1_IRQ;
+	case 5:
+		switch (pin) {
+		case 2:
+			return MACEPCI_SHARED1_IRQ;
+		case 3:
+			return MACEPCI_SHARED2_IRQ;
+		case 4:
+			return MACEPCI_SHARED0_IRQ;
+		case 1:
+		default:
+			return MACEPCI_SLOT2_IRQ;
+		}
+	default:
+		return 0;
+	}
+}
+
+/*
+ * It's not entirely clear what this does in a system with no bridges.
+ * In any case, bridges are not supported by Linux in O2.
+ */
+static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
+{
+	if (PCI_SLOT (dev->devfn) == 2)
+		*pinp = 2;
+	else
+		*pinp = 1;
+	return PCI_SLOT (dev->devfn);
+}
+
+/* All devices are enabled during initialization. */
+int pcibios_enable_device (struct pci_dev *dev)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+char * __init pcibios_setup (char *str)
+{
+	return str;
+}
+
+void __init pcibios_align_resource (void *data, struct resource *res,
+				    unsigned long size)
+{
+}
+
+void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root,
+				     struct resource *res, int resource)
+{
+}
+
+void __init pcibios_update_irq (struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void __init pcibios_fixup_bus (struct pci_bus *b)
+{
+	pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
+}
+
+/* XXX anybody know what this is supposed to do? */
+void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+				      struct pbus_set_ranges_data * ranges)
+{
+	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;
+}
+
+/*
+ * Handle errors from the bridge.  This includes master and target aborts,
+ * various command and address errors, and the interrupt test.  This gets
+ * registered on the bridge error irq.  It's conceivable that some of these
+ * conditions warrant a panic.  Anybody care to say which ones?
+ */
+void macepci_error (int irq, void *dev, struct pt_regs *regs) {
+	u32 flags, error_addr;
+	char space;
+
+	flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
+	error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
+
+	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
+		space = 'M';
+	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
+		space = 'C';
+	else space = 'X';
+
+	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
+		printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_MASTER_ABORT);
+	}
+	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
+		printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_TARGET_ABORT);
+	}
+	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
+		printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_DATA_PARITY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_RETRY_ERR) {
+		printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_RETRY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
+		printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS,
+			       flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
+	}
+	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
+		printk ("MACEPCI: System error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_SYSTEM_ERR);
+	}
+	if (flags & MACEPCI_ERROR_PARITY_ERR) {
+		printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
+			space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_PARITY_ERR);
+	}
+	if (flags & MACEPCI_ERROR_OVERRUN) {
+		printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
+			error_addr, space);
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_OVERRUN);
+	}
+	if (flags & MACEPCI_ERROR_SIG_TABORT) {
+		printk ("MACEPCI: Signaled target abort (clearing)\n");
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_SIG_TABORT);
+	}
+	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
+		printk ("MACEPCI: Interrupt test triggered (clearing)\n");
+		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
+			       & ~MACEPCI_ERROR_INTERRUPT_TEST);
+	}
+}
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-reset.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-reset.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-reset.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-reset.c	Thu Sep 12 20:01:40 2002
@@ -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 -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-rtc.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-rtc.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-rtc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-rtc.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,32 @@
+/*
+ * RTC routines for IP32 style attached 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) 2000 Harald Koerfgen
+ */
+#include <linux/mc146818rtc.h>
+#include <asm/ip32/mace.h>
+
+static unsigned char ip32_rtc_read_data(unsigned long addr)
+{
+	return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8));
+}
+
+static void ip32_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data);
+}
+
+static int ip32_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops ip32_rtc_ops = {
+	&ip32_rtc_read_data,
+	&ip32_rtc_write_data,
+	&ip32_rtc_bcd_mode
+};
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-setup.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-setup.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,102 @@
+/*
+ * IP32 basic setup
+ *
+ * This file is subject to 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
+ */
+#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 <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+#include <asm/sgialib.h>
+
+extern struct rtc_ops ip32_rtc_ops;
+extern u32 cc_interval;
+
+#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
+	char *ctype;
+#endif
+	TLBMISS_HANDLER_SETUP ();
+
+	mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);;
+
+#ifdef CONFIG_SERIAL_CONSOLE
+	ctype = ArcGetEnvironmentVariable("console");
+	if (*ctype == 'd') {
+		if (ctype[1] == '2')
+			console_setup ("ttyS1");
+		else
+			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 ();
+}
+
+int __init page_is_ram (unsigned long pagenr)
+{
+	/* XXX: to do? */
+	return 1;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-timer.c linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-timer.c
--- linux-2.4.20-pre6/arch/mips/sgi-ip32/ip32-timer.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-timer.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,238 @@
+/*
+ * IP32 timer calibration
+ *
+ * This file is subject to 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
+ */
+#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;
+
+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)
+{
+	u64 crime_time;
+	u32 cc_tick;
+
+	printk("Calibrating system timer... ");
+
+	crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
+	cc_tick = read_32bit_cp0_register (CP0_COUNT);
+
+	while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time
+		< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
+		;
+	cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick;
+	cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
+	/* The round-off seems unnecessary; in testing, the error of the
+	 * above procedure is < 100 ticks, which means it gets filtered
+	 * out by the HZ adjustment.
+	 */
+	cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
+
+	printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
+
+	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 -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/Makefile linux-2.4.20-pre7/arch/mips/sibyte/cfe/Makefile
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,8 @@
+USE_STANDARD_AS_RULE := true
+
+L_TARGET = cfe.a
+
+obj-y			= cfe_api.o setup.o
+obj-$(CONFIG_SMP)	+= smp.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_api.c linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_api.c
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_api.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_api.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,404 @@
+/*
+ * 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"
+
+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)
+{
+	if ((*((unsigned int *) (int) CFE_APISEAL) == CFE_EPTSEAL) ||
+	    (*((unsigned int *) (int) CFE_APISEAL_RE) == CFE_EPTSEAL) ||
+	    (*((unsigned int *) (int) CFE_APISEAL_OLD) == CFE_EPTSEAL)) {
+		cfe_dispfunc = (cfe_xptr_t) (int) CFE_APIENTRY;
+		if (handle) cfe_handle = handle;
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+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(const char *str, int len)
+{
+	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 -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_api.h linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_api.h
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_api.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_api.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,71 @@
+/*
+ * 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)
+    *
+    ********************************************************************* */
+
+#include <linux/config.h>
+
+#define CFE_EPTSEAL 0x43464531
+#ifdef CONFIG_MIPS_UNCACHED
+#define CFE_APIENTRY    0xBFC00500
+#define CFE_APISEAL     0xBFC004E0
+#define CFE_APISEAL_RE  0xBFC004E8
+#define CFE_APISEAL_OLD 0xBFC00508
+#else
+#define CFE_APIENTRY    0x9FC00500
+#define CFE_APISEAL     0x9FC004E0
+#define CFE_APISEAL_RE  0x9FC004E8
+#define CFE_APISEAL_OLD 0x9FC00508
+#endif
+
+#ifndef __ASSEMBLER__
+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(const char *, int);
+#endif
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_error.h linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_error.h
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_error.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_error.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,76 @@
+/*
+ * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_xiocb.h linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_xiocb.h
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/cfe_xiocb.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/cfe_xiocb.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,177 @@
+/*
+ * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/setup.c linux-2.4.20-pre7/arch/mips/sibyte/cfe/setup.c
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,387 @@
+/*
+ * 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 <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+#include <linux/console.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/sibyte/board.h>
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+#include "cfe_error.h"
+
+/* Max ram addressable in 32-bit segments */
+#ifdef CONFIG_MIPS64
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#define MAX_RAM_SIZE (0xffffffffULL)
+#endif
+#else
+#define MAX_RAM_SIZE (0x1fffffffULL)
+#endif
+#endif
+
+#define SB1250_DUART_MINOR_BASE		192 /* XXXKW put this somewhere sane */
+#define SB1250_PROMICE_MINOR_BASE	191 /* XXXKW put this somewhere sane */
+kdev_t cfe_consdev;
+
+#define SIBYTE_MAX_MEM_REGIONS 8
+phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS];
+phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS];
+unsigned int board_mem_region_count;
+
+/* 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
+
+#ifdef CONFIG_SMP
+static int reboot_smp = 0;
+#endif
+
+static void cfe_linux_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id()) {
+		if (reboot_smp) {
+			/* Don't repeat the process from another CPU */
+			for (;;);
+		} else {
+			/* Get CPU 0 to do the cfe_exit */
+			reboot_smp = 1;
+			smp_call_function((void *)_machine_restart, NULL, 1, 0);
+			for (;;);
+		}
+	}
+#endif
+	printk("passing control back to CFE\n");
+	cfe_exit(1, 0);
+	printk("cfe_exit returned??\n");
+	while(1);
+}
+
+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))) {
+		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;
+				/*
+				 * memcpy/__copy_user prefetch, which
+				 * will cause a bus error for
+				 * KSEG/KUSEG addrs not backed by RAM.
+				 * Hence, reserve some padding for the
+				 * prefetch distance.
+				 */
+				if (size > 512)
+					size -= 512;
+				add_memory_region(addr, size, BOOT_MEM_RAM);
+			}
+			board_mem_region_addrs[board_mem_region_count] = addr;
+			board_mem_region_sizes[board_mem_region_count] = size;
+			board_mem_region_count++;
+			if (board_mem_region_count ==
+			    SIBYTE_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) {
+		*(tmp-1) = '@';
+		goto fail;
+	}
+	*(tmp-1) = '@';
+	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)
+{
+	_machine_restart   = (void (*)(char *))cfe_linux_exit;
+	_machine_halt      = cfe_linux_exit;
+	_machine_power_off = cfe_linux_exit;
+
+	/*
+	 * 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 ");
+#ifdef CONFIG_SIBYTE_PTSWARM
+			strcat(arcs_cmdline, "console=ttyS0,115200 ");
+#endif
+		} else {
+			/* The loader should have set the command line */
+			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 */
+}
+
+int page_is_ram(unsigned long pagenr)
+{
+	phys_t addr = pagenr << PAGE_SHIFT;
+	int i;
+	for (i = 0; i < board_mem_region_count; i++) {
+		if ((addr >= board_mem_region_addrs[i])
+		    && (addr < (board_mem_region_addrs[i] + board_mem_region_sizes[i]))) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+#ifdef CONFIG_SIBYTE_CFE_CONSOLE
+
+static void cfe_console_write(struct console *cons, const char *str,
+                              unsigned int count)
+{
+	int i, last;
+
+	for (i=0,last=0; i<count; i++) {
+		if (!str[i])
+			/* XXXKW can/should this ever happen? */
+			panic("cfe_console_write with NULL");
+		if (str[i] == '\n') {
+			cfe_console_print(&str[last], i-last);
+			cfe_console_print("\r", 1);
+			last = i;
+		}
+	}
+	if (last != count)
+		cfe_console_print(&str[last], count-last);
+}
+
+static kdev_t cfe_console_device(struct console *c)
+{
+	return cfe_consdev;
+}
+
+static int cfe_console_setup(struct console *cons, char *str)
+{
+	char consdev[32];
+	cfe_open_console();
+	/* XXXKW think about interaction with 'console=' cmdline arg */
+	/* If none of the console options are configured, the build will break. */
+	if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) {
+#ifdef CONFIG_SIBYTE_SB1250_DUART
+		if (!strcmp(consdev, "uart0")) {
+			setleds("u0cn");
+			cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 0);
+#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1
+		} else if (!strcmp(consdev, "uart1")) {
+			setleds("u1cn");
+			cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 1);
+#endif
+#endif
+#ifdef CONFIG_VGA_CONSOLE
+		} else if (!strcmp(consdev, "pcconsole0")) {
+			setleds("pccn");
+			cfe_consdev = MKDEV(TTY_MAJOR, 0);
+#endif
+#ifdef CONFIG_PROMICE
+		} else if (!strcmp(consdev, "promice0")) {
+			setleds("picn");
+			cfe_consdev = MKDEV(TTY_MAJOR, SB1250_PROMICE_MINOR_BASE);
+#endif
+		} else
+			return -ENODEV;
+	}
+	return 0;
+}
+
+static struct console sb1250_cfe_cons = {
+	name:		"cfe",
+	write:		cfe_console_write,
+	device:		cfe_console_device,
+	setup:		cfe_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+void __init sb1250_cfe_console_init(void)
+{
+	register_console(&sb1250_cfe_cons);
+}
+
+#endif /* CONFIG_SIBYTE_CFE_CONSOLE */
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/cfe/smp.c linux-2.4.20-pre7/arch/mips/sibyte/cfe/smp.c
--- linux-2.4.20-pre6/arch/mips/sibyte/cfe/smp.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/cfe/smp.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,79 @@
+/*
+ * 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/sched.h>
+#include <linux/smp.h>
+
+#include <asm/mipsregs.h>
+
+#include "cfe_xiocb.h"
+#include "cfe_api.h"
+#include "cfe_error.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();
+}
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1/cache_err_handler.S linux-2.4.20-pre7/arch/mips/sibyte/sb1/cache_err_handler.S
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1/cache_err_handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1/cache_err_handler.S	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -20,6 +20,7 @@
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/sibyte/board.h>
 
 	.text
 	/* Special Cache Error handler for SB1 for now */
@@ -36,13 +37,12 @@
 	#.set	mips64
 	.set	mips4
 	.set	reorder
-	# look for signature of spurious CErr
+#ifdef CONFIG_SB1_CERR_IGNORE_RECOVERABLE
 	mfc0	k1, $26				# mfc0	k1, $26, 0
 	# check if error was recoverable
 	# XXXKW - count them
 	bltz	k1, leave_cerr
-	 nop
-
+#endif
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 	# look for signature of spurious CErr
 	lui	k0, 0x4000
@@ -51,13 +51,32 @@
 	lui	k0, 0xffe0
 	and	k1, k0, k1
 	lui	k0, 0x0200
-	bne	k0, k1, real_cerr
-	 nop
+	beq	k0, k1, leave_cerr
+	# XXXKW - count them
+#endif
+
+real_cerr:
+#ifdef CONFIG_SB1_CERR_SPIN
+        setleds(k0,k1,'C','E','R','R')
+
+1:	b	1b
 #else
-	j	real_cerr
-	 nop
+	mfc0	k0,CP0_CONFIG
+	li	k1,~CONF_CM_CMASK
+	and	k0,k0,k1
+	ori	k0,k0,CONF_CM_UNCACHED
+	mtc0	k0,CP0_CONFIG
+
+	SSNOP
+	SSNOP
+	SSNOP
+	SSNOP
+	bnezl	$0, 1f
+1:
+	j	sb1_cache_error
 #endif
-	# XXXKW - count spurious errors
+
+#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || defined(CONFIG_SB1_CERR_IGNORE_RECOVERABLE)
 leave_cerr:
 	# clear/unlock the registers
 	mtc0	zero, $26			# mtc0	zero, $26, 0
@@ -65,23 +84,7 @@
 	.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
+#endif
 
 	.set	pop
 	END(except_vec2_sb1)
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1/cache_error.c linux-2.4.20-pre7/arch/mips/sibyte/sb1/cache_error.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1/cache_error.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1/cache_error.c	Thu Sep 12 20:01:40 2002
@@ -16,10 +16,14 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include <linux/kernel.h>
+#include <linux/sched.h>
 #include <asm/mipsregs.h>
 
 /* SB1 definitions */
+
+/* XXX should come from config1 XXX */
+#define SB1_CACHE_INDEX_MASK   0x1fe0
+
 #define CP0_ERRCTL_RECOVERABLE (1 << 31)
 #define CP0_ERRCTL_DCACHE      (1 << 30)
 #define CP0_ERRCTL_ICACHE      (1 << 29)
@@ -30,7 +34,9 @@
 #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_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL))
+#define CP0_CERRI_DATA         (CP0_CERRI_DATA_PARITY)
 
 #define CP0_CERRD_MULTIPLE     (1 << 31)
 #define CP0_CERRD_TAG_STATE    (1 << 30)
@@ -43,38 +49,463 @@
 #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)
+#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL))
+#define CP0_CERRD_IDX_VALID(c) \
+   (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0)
+#define CP0_CERRD_CAUSES \
+   (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG)
+#define CP0_CERRD_TYPES \
+   (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL)
+#define CP0_CERRD_DATA         (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE)
+
+static uint32_t	extract_ic(unsigned short addr, int data);
+static uint32_t	extract_dc(unsigned short addr, int data);
+
+spinlock_t in_cacheerr = SPIN_LOCK_UNLOCKED;
+
+static inline void breakout_errctl(unsigned int val)
 {
-	unsigned int errctl, cerr_i, cerr_d, cerr_dpa;
-	unsigned long eepc;
+	if (val & CP0_ERRCTL_RECOVERABLE)
+		printk(" recoverable");
+	if (val & CP0_ERRCTL_DCACHE)
+		printk(" dcache");
+	if (val & CP0_ERRCTL_ICACHE)
+		printk(" icache");
+	if (val & CP0_ERRCTL_MULTIBUS)
+		printk(" multiple-buserr");
+	printk("\n");
+}
 
-	eepc = get_errorepc();
+static inline void breakout_cerri(unsigned int val)
+{
+	if (val & CP0_CERRI_TAG_PARITY)
+		printk(" tag-parity");
+	if (val & CP0_CERRI_DATA_PARITY)
+		printk(" data-parity");
+	if (val & CP0_CERRI_EXTERNAL)
+		printk(" external");
+	printk("\n");
+}
+
+static inline void breakout_cerrd(unsigned int val)
+{
+	switch (val & CP0_CERRD_CAUSES) {
+	case CP0_CERRD_LOAD:
+		printk(" load,");
+		break;
+	case CP0_CERRD_STORE:
+		printk(" store,");
+		break;
+	case CP0_CERRD_FILLWB:
+		printk(" fill/wb,");
+		break;
+	case CP0_CERRD_COHERENCY:
+		printk(" coherency,");
+		break;
+	case CP0_CERRD_DUPTAG:
+		printk(" duptags,");
+		break;
+	default:
+		printk(" NO CAUSE,");
+		break;
+	}
+	if (!(val & CP0_CERRD_TYPES))
+		printk(" NO TYPE");
+	else {
+		if (val & CP0_CERRD_MULTIPLE)
+			printk(" multi-err");
+		if (val & CP0_CERRD_TAG_STATE)
+			printk(" tag-state");
+		if (val & CP0_CERRD_TAG_ADDRESS)
+			printk(" tag-address");
+		if (val & CP0_CERRD_DATA_SBE)
+			printk(" data-SBE");
+		if (val & CP0_CERRD_DATA_DBE)
+			printk(" data-DBE");
+		if (val & CP0_CERRD_EXTERNAL)
+			printk(" external");
+	}
+	printk("\n");
+}
 
+asmlinkage void sb1_cache_error(void)
+{
+	uint64_t cerr_dpa;
+	uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+
+	/* Prevent re-entrance in the SMP case */
+	spin_lock(&in_cacheerr);
+	printk("Cache error exception on CPU %x:\n",
+	       (read_32bit_cp0_register(CP0_PRID) >> 25) & 0x7);
 	__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 push\n\t"
+		".set mips64\n\t"
+		".set noat\n\t"
+		"mfc0   %0, $26, 0\n\t"
+		"mfc0   %1, $27, 0\n\t"
+		"mfc0   %2, $27, 1\n\t"
+		"dmfc0  $1, $27, 3\n\t"
+		"dsrl32 %3, $1, 0 \n\t"
+		"sll    %4, $1, 0 \n\t"
+		"mfc0   %5, $30\n\t"
 		".set pop\n"
-		: "=r" (errctl), "=r" (cerr_i),
-		  "=r" (cerr_d), "=r" (cerr_dpa));
+		: "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d),
+		  "=r" (dpahi), "=r" (dpalo), "=r" (eepc));
+	cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
+	printk(" cp0_errorepc ==   %08x\n", eepc);
+	printk(" cp0_errctl   ==   %08x", errctl);
+	breakout_errctl(errctl);
+	if (errctl & CP0_ERRCTL_ICACHE) {
+		printk(" cp0_cerr_i   ==   %08x", cerr_i);
+		breakout_cerri(cerr_i);
+		if (CP0_CERRI_IDX_VALID(cerr_i)) {
+			if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK))
+				printk(" cerr_i idx doesn't match eepc\n");
+			else {
+				res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
+						 (cerr_i & CP0_CERRI_DATA) != 0);
+				if (!(res & cerr_i))
+					printk("...didn't see indicated icache problem\n");
+			}
+		}
+	}
+	if (errctl & CP0_ERRCTL_DCACHE) {
+		printk(" cp0_cerr_d   ==   %08x", cerr_d);
+		breakout_cerrd(cerr_d);
+		if (CP0_CERRD_DPA_VALID(cerr_d)) {
+			printk(" cp0_cerr_dpa == %010llx\n", cerr_dpa);
+			if (!CP0_CERRD_IDX_VALID(cerr_d)) {
+				res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
+						 (cerr_d & CP0_CERRD_DATA) != 0);
+				if (!(res & cerr_d))
+					printk("...didn't see indicated dcache problem\n");
+			} else {
+				if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
+					printk(" cerr_d idx doesn't match cerr_dpa\n");
+				else {
+					res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
+							 (cerr_d & CP0_CERRD_DATA) != 0);
+					if (!(res & cerr_d))
+						printk("...didn't see indicated problem\n");
+				}
+			}
+		}
+	}
 
-	printk("Cache error exception:\n");
-	printk(" cp0_errorepc == 0x%0lx\n", eepc);
-	printk(" cp0_errctl   == 0x%08x\n", errctl);
+	while (1);
+	/*
+	 * This tends to make things get really ugly; let's just stall instead.
+	 *    panic("Can't handle the cache error!");
+	 */
+}
 
-	if (errctl & CP0_ERRCTL_DCACHE) {
-		printk(" cp0_cerr_d   == 0x%08x\n", cerr_d);
-		printk(" cp0_cerr_dpa == 0x%08x\n", cerr_dpa);
+
+/* Parity lookup table. */
+static const uint8_t parity[256] = {
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+	1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
+};
+
+/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
+static const uint64_t mask_72_64[8] = {
+	0x0738C808099264FFL,
+	0x38C808099264FF07L,
+	0xC808099264FF0738L,
+	0x08099264FF0738C8L,
+	0x099264FF0738C808L,
+	0x9264FF0738C80809L,
+	0x64FF0738C8080992L,
+	0xFF0738C808099264L
+};
+
+/* Calculate the parity on a range of bits */
+static char range_parity(uint64_t dword, int max, int min)
+{
+	char parity = 0;
+	int i;
+	dword >>= min;
+	for (i=max-min; i>=0; i--) {
+		if (dword & 0x1)
+			parity = !parity;
+		dword >>= 1;
 	}
-	if (errctl & CP0_ERRCTL_ICACHE) {
-		printk(" cp0_cerr_i   == 0x%08x\n", cerr_i);
+	return parity;
+}
+
+/* Calculate the 4-bit even byte-parity for an instruction */
+static unsigned char inst_parity(uint32_t word)
+{
+	int i, j;
+	char parity = 0;
+	for (j=0; j<4; j++) {
+		char byte_parity = 0;
+		for (i=0; i<8; i++) {
+			if (word & 0x80000000)
+				byte_parity = !byte_parity;
+			word <<= 1;
+		}
+		parity <<= 1;
+		parity |= byte_parity;
 	}
+	return parity;
+}
+
+static uint32_t extract_ic(unsigned short addr, int data)
+{
+	unsigned short way;
+	int valid;
+	uint64_t taglo, va, tlo_tmp;
+	uint32_t taghi, taglolo, taglohi;
+	uint8_t lru;
+	int res = 0;
+
+	printk("Icache index 0x%04x  ", addr);
+	for (way = 0; way < 4; way++) {
+		/* Index-load-tag-I */
+		__asm__ __volatile__ (
+			".set push        \n\t"
+			".set noreorder   \n\t"
+			".set mips64      \n\t"
+			".set noat        \n\t"
+			"cache  4, 0(%3)  \n\t"
+			"mfc0   %0, $29, 0\n\t"
+			"dmfc0  $1, $28, 0\n\t"
+			"dsrl32 %1, $1, 0 \n\t"
+			"sll    %2, $1, 0 \n\t"
+			".set pop         \n"
+			: "=r" (taghi), "=r" (taglohi),
+			  "=r" (taglolo)
+			: "r" ((way << 13) | addr));
+		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+		if (way == 0) {
+			lru = (taghi >> 14) & 0xff;
+			printk("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+			       ((addr >> 5) & 0x3), /* bank */
+			       ((addr >> 7) & 0x3f), /* index */
+			       (lru & 0x3),
+			       ((lru >> 2) & 0x3),
+			       ((lru >> 4) & 0x3),
+			       ((lru >> 6) & 0x3));
+		}
+		va = (taglo & 0xC0000FFFFFFFE000) | addr;
+		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
+			va |= 0x3FFFF00000000000;
+		valid = ((taghi >> 29) & 1);
+		if (valid) {
+			tlo_tmp = taglo & 0xfff3ff;
+			if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
+				printk("   ** bad parity in VTag0/G/ASID\n");
+				res |= CP0_CERRI_TAG_PARITY;
+			}
+			if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
+				printk("   ** bad parity in R/VTag1\n");
+				res |= CP0_CERRI_TAG_PARITY;
+			}
+		}
+		if (valid ^ ((taghi >> 27) & 1)) {
+			printk("   ** bad parity for valid bit\n");
+			res |= CP0_CERRI_TAG_PARITY;
+		}
+		printk(" %d  [VA %016llx]  [Vld? %d]  raw tags: %08X-%016llX\n",
+		       way, va, valid, taghi, taglo);
+
+		if (data) {
+			uint32_t datahi, insta, instb;
+			uint8_t predecode;
+			int offset;
 
-	panic("Can't handle the cache error!");
+			/* (hit all banks and ways) */
+			for (offset = 0; offset < 4; offset++) {
+				/* Index-load-data-I */
+				__asm__ __volatile__ (
+					".set push        \n\t"
+					".set noreorder   \n\t"
+					".set mips64      \n\t"
+					".set noat        \n\t"
+					"cache  6, 0(%3)  \n\t"
+					"mfc0   %0, $29, 1\n\t"
+					"dmfc0  $1, $28, 1\n\t"
+					"dsrl32 %1, $1, 0 \n\t"
+					"sll    %2, $1, 0 \n\t"
+					".set pop         \n"
+					: "=r" (datahi), "=r" (insta),
+					  "=r" (instb)
+					: "r" ((way << 13) | addr | (offset << 3)));
+				predecode = (datahi >> 8) & 0xff;
+				if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
+					printk("   ** bad parity in predecode\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				/* XXXKW should/could check predecode bits themselves */
+				if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
+					printk("   ** bad parity in instruction a\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				if ((datahi & 0xf) ^ inst_parity(instb)) {
+					printk("   ** bad parity in instruction b\n");
+					res |= CP0_CERRI_DATA_PARITY;
+				}
+				printk("  %05X-%08X%08X", datahi, insta, instb);
+			}
+			printk("\n");
+		}
+	}
+	return res;
+}
+
+/* Compute the ECC for a data doubleword */
+static uint8_t dc_ecc(uint64_t dword)
+{
+	uint64_t t;
+	uint32_t w;
+	uint8_t  p;
+	int      i;
+
+	p = 0;
+	for (i = 7; i >= 0; i--)
+	{
+		p <<= 1;
+		t = dword & mask_72_64[i];
+		w = (uint32_t)(t >> 32);
+		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+		w = (uint32_t)(t & 0xFFFFFFFF);
+		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+	}
+	return p;
+}
+
+struct dc_state {
+	unsigned char val;
+	char *name;
+};
+
+static struct dc_state dc_states[] = {
+	{ 0x00, "INVALID" },
+	{ 0x0f, "COH-SHD" },
+	{ 0x13, "NCO-E-C" },
+	{ 0x19, "NCO-E-D" },
+	{ 0x16, "COH-E-C" },
+	{ 0x1c, "COH-E-D" },
+	{ 0xff, "*ERROR*" }
+};
+
+#define DC_TAG_VALID(state) \
+    (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c))
+
+static char *dc_state_str(unsigned char state)
+{
+	struct dc_state *dsc = dc_states;
+	while (dsc->val != 0xff) {
+		if (dsc->val == state)
+			break;
+		dsc++;
+	}
+	return dsc->name;
+}
+
+static uint32_t extract_dc(unsigned short addr, int data)
+{
+	int valid, way;
+	unsigned char state;
+	uint64_t taglo, pa;
+	uint32_t taghi, taglolo, taglohi;
+	uint8_t ecc, lru;
+	int res = 0;
+
+	printk("Dcache index 0x%04x  ", addr);
+	for (way = 0; way < 4; way++) {
+		/* Index-load-tag-D */
+		__asm__ __volatile__ (
+			".set push        \n\t"
+			".set noreorder   \n\t"
+			".set mips64      \n\t"
+			".set noat        \n\t"
+			"cache  5, 0(%3)  \n\t"
+			"mfc0   %0, $29, 2\n\t"
+			"dmfc0  $1, $28, 2\n\t"
+			"dsrl32 %1, $1, 0 \n\t"
+			"sll    %2, $1, 0 \n\t"
+			".set pop         \n"
+			: "=r" (taghi), "=r" (taglohi),
+			  "=r" (taglolo)
+			: "r" ((way << 13) | addr));
+
+		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+		pa = (taglo & 0xFFFFFFE000) | addr;
+		if (way == 0) {
+			lru = (taghi >> 14) & 0xff;
+			printk("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+			       ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
+			       ((addr >> 6) & 0x3f), /* index */
+			       (lru & 0x3),
+			       ((lru >> 2) & 0x3),
+			       ((lru >> 4) & 0x3),
+			       ((lru >> 6) & 0x3));
+		}
+		state = (taghi >> 25) & 0x1f;
+		valid = DC_TAG_VALID(state);
+		printk(" %d  [PA %010llx]  [state %s (%02x)]  raw tags: %08X-%016llX\n",
+		       way, pa, dc_state_str(state), state, taghi, taglo);
+		if (valid) {
+			if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
+				printk("   ** bad parity in PTag1\n");
+				res |= CP0_CERRD_TAG_ADDRESS;
+			}
+			if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
+				printk("   ** bad parity in PTag0\n");
+				res |= CP0_CERRD_TAG_ADDRESS;
+			}
+		} else {
+			res |= CP0_CERRD_TAG_STATE;
+		}
+
+		if (data) {
+			uint64_t datalo;
+			uint32_t datalohi, datalolo, datahi;
+			int offset;
+
+			for (offset = 0; offset < 4; offset++) {
+				/* Index-load-data-D */
+				__asm__ __volatile__ (
+					".set push        \n\t"
+					".set noreorder   \n\t"
+					".set mips64      \n\t"
+					".set noat        \n\t"
+					"cache  7, 0(%3)  \n\t"
+					"mfc0   %0, $29, 3\n\t"
+					"dmfc0  $1, $28, 3\n\t"
+					"dsrl32 %1, $1, 0 \n\t"
+					"sll    %2, $1, 0 \n\t"
+					".set pop         \n"
+					: "=r" (datahi), "=r" (datalohi),
+					"=r" (datalolo)
+					: "r" ((way << 13) | addr | (offset << 3)));
+				datalo = ((unsigned long long)datalohi << 32) | datalolo;
+				ecc = dc_ecc(datalo);
+				if (ecc != datahi) {
+					int bits = 0;
+					printk("  ** bad ECC (%02x %02x) ->",
+					       datahi, ecc);
+					ecc ^= datahi;
+					while (ecc) {
+						if (ecc & 1) bits++;
+						ecc >>= 1;
+					}
+					res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
+				}
+				printk("  %02X-%016llX", datahi, datalo);
+			}
+			printk("\n");
+		}
+	}
+	return res;
 }
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/Makefile linux-2.4.20-pre7/arch/mips/sibyte/sb1250/Makefile
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/Makefile	Thu Sep 12 20:01:40 2002
@@ -2,11 +2,12 @@
 
 O_TARGET := sb1250.o
 
-obj-y := irq.o irq_handler.o time.o
+obj-y := setup.o 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
+obj-$(CONFIG_SIBYTE_STANDALONE)	+= prom.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -50,20 +50,26 @@
  * 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
+/* 100 samples per second on a 500 Mhz 1250 */
+#define TB_PERIOD 2500000ULL
 
 static void arm_tb(void)
 {
+        unsigned long long scdperfcnt;
 	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
+	scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG);
+	/* Unfortunately, in Pass 2 we must clear all counters to knock down
+	   a previous interrupt request.  This means that bus profiling
+	   requires ALL of the SCD perf counters. */
+	out64((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
 		   M_SPC_CFG_ENABLE |		 // enable counting
+		   M_SPC_CFG_CLEAR |		 // clear all counters
 		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
 	      KSEG1 + A_SCD_PERF_CNT_CFG);
 	out64(next, KSEG1 + A_SCD_PERF_CNT_1);
@@ -150,17 +156,17 @@
 	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);
@@ -171,7 +177,7 @@
 	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,
@@ -252,7 +258,7 @@
 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;
@@ -269,7 +275,7 @@
 	return 0;
 }
 
-static ssize_t sbprof_tb_read(struct file *filp, char *buf, 
+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;
@@ -309,9 +315,9 @@
 #define SBPROF_ZBSTOP	_IOW('s', 1, int)
 #define SBPROF_ZBFULL	_IOW('s', 2, int)
 
-static int sbprof_tb_ioctl(struct inode *inode, 
+static int sbprof_tb_ioctl(struct inode *inode,
 			struct file *filp,
-			unsigned int command, 
+			unsigned int command,
 			unsigned long arg)
 {
 	int error = 0;
@@ -346,7 +352,7 @@
 
 static devfs_handle_t devfs_handle;
 
-static int __init sbprof_tb_init(void) 
+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",
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/bcm1250_tbprof.h linux-2.4.20-pre7/arch/mips/sibyte/sb1250/bcm1250_tbprof.h
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/bcm1250_tbprof.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/bcm1250_tbprof.h	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/irq.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/irq.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/irq.c	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -23,21 +23,24 @@
 #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_uart.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. 
+ * 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 
+ * for interrupt lines
  */
 
 
@@ -50,6 +53,15 @@
 
 #ifdef CONFIG_REMOTE_DEBUG
 extern void breakpoint(void);
+extern void set_debug_traps(void);
+
+/* kgdb is on when configured.  Pass "nokgdb" kernel arg to turn it off */
+static int kgdb_flag = 1;
+static int __init nokgdb(char *str)
+{
+	kgdb_flag = 0;
+}
+__setup("nokgdb", nokgdb);
 #endif
 
 #define NR_IRQS 64
@@ -155,11 +167,44 @@
 }
 
 
+static void sb1250_dummy_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+}
+
+static struct irqaction sb1250_dummy_action = {
+	handler: sb1250_dummy_handler,
+	flags:   0,
+	mask:    0,
+	name:    "sb1250-private",
+	next:    NULL,
+	dev_id:  0
+};
+
+int sb1250_steal_irq(int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+	int retval = 0;
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&desc->lock,flags);
+	/* Don't allow sharing at all for these */
+	if (desc->action != NULL)
+		retval = -EBUSY;
+	else {
+		desc->action = &sb1250_dummy_action;
+		desc->depth = 0;
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+}
+
 /*
  *  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. 
+ *  "right" place.
  */
 /*
  * For now, map all interrupts to IP[2].  We could save
@@ -167,10 +212,10 @@
  * 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. 
- * 
+ * 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 
+ * 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
  */
@@ -178,12 +223,16 @@
 #define IMR_IP2_VAL	K_INT_MAP_I0
 #define IMR_IP3_VAL	K_INT_MAP_I1
 #define IMR_IP4_VAL	K_INT_MAP_I2
+#define IMR_IP5_VAL	K_INT_MAP_I3
+#define IMR_IP6_VAL	K_INT_MAP_I4
 
 void __init init_IRQ(void)
 {
 
 	unsigned int i;
 	u64 tmp;
+	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+		STATUSF_IP1 | STATUSF_IP0;
 
 	/* Default everything to IP2 */
 	for (i = 0; i < NR_IRQS; i++) {	/* was I0 */
@@ -220,26 +269,60 @@
 	out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
 	out64(tmp, KSEG1 + A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK));
 
+	sb1250_steal_irq(K_INT_MBOX_0);
+
 	/*
-	 * Note that the timer interrupts are also mapped, but this is 
+	 * 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);
+#ifdef CONFIG_BCM1250_PROF
+	imask |= STATUSF_IP7;
+#endif
+#ifdef CONFIG_REMOTE_DEBUG
+	imask |= STATUSF_IP6;
 #endif
+	/* Enable necessary IPs, disable the rest */
+	change_cp0_status(ST0_IM, imask);
 	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();
+	if (kgdb_flag) {
+		/* Setup uart 1 settings, mapper */
+		out64(M_DUART_IMR_BRK, KSEG1 + A_DUART + R_DUART_IMR_B);
+
+		out64(IMR_IP6_VAL,
+			KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_UART_1<<3));
+		tmp = in64(KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
+		tmp &= ~(1<<K_INT_UART_1);
+		out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK));
+
+		set_debug_traps();
+		breakpoint();
+	}
 #endif
 }
+
+#ifdef CONFIG_REMOTE_DEBUG
+
+#include <linux/delay.h>
+
+extern void set_async_breakpoint(unsigned int epc);
+
+#define duart_out(reg, val)     out64(val, KSEG1 + A_DUART_CHANREG(1,reg))
+#define duart_in(reg)           in64(KSEG1 + A_DUART_CHANREG(1,reg))
+
+void sb1250_kgdb_interrupt(struct pt_regs *regs)
+{
+	/*
+	 * Clear break-change status (allow some time for the remote
+	 * host to stop the break, since we would see another
+	 * interrupt on the end-of-break too)
+	 */
+	mdelay(500);
+	duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
+				M_DUART_RX_EN | M_DUART_TX_EN);
+	if (!user_mode(regs))
+		set_async_breakpoint(regs->cp0_epc);
+}
+#endif 	/* CONFIG_REMOTE_DEBUG */
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/irq_handler.S linux-2.4.20-pre7/arch/mips/sibyte/sb1250/irq_handler.S
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/irq_handler.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/irq_handler.S	Thu Sep 12 20:01:40 2002
@@ -10,12 +10,12 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
@@ -23,10 +23,10 @@
  *
  * 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 
- * 
+ * 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. 
+ * This is more BSDish than the Indy code, and also, IMHO, more sane.
  */
 #include <linux/config.h>
 
@@ -40,15 +40,15 @@
 #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 
+ * 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
@@ -77,8 +77,13 @@
 	mfc0	a0, CP0_EPC
 	jal	sbprof_cpu_intr
 	 addu	a0, a0, t1		/* a0 = EPC + (BD ? 4 :	0) */
+	/* Re-enable interrupts here so that events due to sbprof_cpu_intr
+	   get charged to ret_from_irq (via a recursive interrupt)
+	   rather than the restart pc. */
+	mfc0	t0, CP0_STATUS
+	or	t0, ST0_IE
 	j	ret_from_irq
-	 nop				# delay slot
+	 mtc0	t0, CP0_STATUS		# delay slot
 0:
 #endif
 	/* Timer interrupt is routed to IP[4] */
@@ -97,12 +102,24 @@
 	beqz	 t1, 2f
          nop
 	jal	 sb1250_mailbox_interrupt
-	 move    a0, sp		
+	 move    a0, sp
 	j	ret_from_irq
 	 nop				# delay slot
 2:
 #endif
 
+#ifdef CONFIG_REMOTE_DEBUG
+	/* KGDB (uart 1) interrupt is routed to IP[6] */
+	andi	t1, s0, CAUSEF_IP6
+	beqz	t1, 1f
+	nop                            # delay slot
+	jal	sb1250_kgdb_interrupt
+         move	a0, sp
+	j	ret_from_irq
+	nop                            # delay slot
+1:
+#endif
+
 	and      t1, s0, CAUSEF_IP2
 	beqz     t1, 4f
 	 nop
@@ -120,7 +137,7 @@
 3:	#dclz	s1, s0		/* Find the next interrupt */
 	.word   0x72118824	# dclz s1, s0
 	dsubu	a0, zero, s1
-	daddiu	a0, a0, 63     
+	daddiu	a0, a0, 63
 	jal	 do_IRQ
 	 nop
 
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/lib_hssubr.S linux-2.4.20-pre7/arch/mips/sibyte/sb1250/lib_hssubr.S
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/lib_hssubr.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/lib_hssubr.S	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -22,7 +22,7 @@
 
 		 .set mips64
 
-#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP 
+#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP
 
 
 /*  *********************************************************************
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/lib_hssubr.h linux-2.4.20-pre7/arch/mips/sibyte/sb1250/lib_hssubr.h
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/lib_hssubr.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/lib_hssubr.h	Thu Sep 12 20:01:40 2002
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2000, 2001 Broadcom Corporation
+ * Copyright (C) 2002 Ralf Baechle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,45 +11,71 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
+#include <linux/config.h>
+#include <asm/addrspace.h>
 
 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))
+#ifdef CONFIG_MIPS64
 
-#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);
+static inline void hs_write8(hsaddr_t a, uint8_t b)
+{
+	*(volatile uint8_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline void hs_write16(hsaddr_t a, uint16_t b)
+{
+	*(volatile uint16_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline void hs_write32(hsaddr_t a, uint32_t b)
+{
+	*(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline void hs_write64(hsaddr_t a, uint64_t b)
+{
+	*(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b);
+}
+
+static inline uint8_t hs_read8(hsaddr_t a)
+{
+	return *(volatile uint8_t *) a;
+}
+
+static inline uint16_t hs_read16(hsaddr_t a)
+{
+	return *(volatile uint16_t *) a;
+}
+
+static inline uint32_t hs_read32(hsaddr_t a)
+{
+	return *(volatile uint32_t *) a;
+}
+
+static inline uint64_t hs_read64(hsaddr_t a)
+{
+	return *(volatile uint64_t *) a;
+}
+
+#else	/* just CONFIG_MIPS32 */
+
+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
+#endif /* _LIB_HSSUBR_H */
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/pci.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/pci.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/pci.c	Thu Sep 12 20:01:40 2002
@@ -10,20 +10,20 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
+ * BCM1250-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.
@@ -41,9 +41,11 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/console.h>
 
 #include <asm/sibyte/sb1250_defs.h>
 #include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
 #include <asm/io.h>
 
 #include "lib_hssubr.h"
@@ -56,11 +58,8 @@
 #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.
+ * Using the above offset, this macro calcuates the physical address in the
+ * config space.
  */
 #define CFGADDR(dev,where) (A_PHYS_LDTPCI_CFG_MATCH_BITS + \
 			    CFGOFFSET(dev->bus->number,dev->devfn,where))
@@ -68,17 +67,22 @@
 /*
  * Read/write 32-bit values in config space.
  */
+static inline u32 READCFG32(u32 addr)
+{
+	hs_read32(addr & ~3);
+}
 
-#define READCFG32(addr) hs_read32((addr)&~3)
-#define WRITECFG32(addr,data) hs_write32(((addr)&~3),(data))
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+	return 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.
+ * 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
@@ -153,7 +157,6 @@
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-
 	data = READCFG32(cfgaddr);
 
 	/*
@@ -232,12 +235,14 @@
 void __init pcibios_init(void)
 {
 	uint32_t cmdreg;
+	uint64_t reg;
 
 	/*
 	 * See if the PCI bus has been configured by the firmware.
 	 */
 
-	cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) + PCI_COMMAND);
+	cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) +
+			   PCI_COMMAND);
 
 	if (!(cmdreg & PCI_COMMAND_MASTER)) {
 		printk
@@ -245,22 +250,31 @@
 		return;
 	}
 
+	reg = *((volatile uint64_t *) KSEG1ADDR(A_SCD_SYSTEM_CFG));
+	if (!(reg & M_SYS_PCI_HOST)) {
+		printk("PCI: Skipping PCI probe.  Processor is in PCI device mode.\n");
+		return;
+	}
+
 	sb1250_bus_status |= PCI_BUS_ENABLED;
 
-	/* 
-	 * Establish a mapping from KSEG2 (kernel virtual) to PCI I/O space 
+	/*
+	 * 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));
+	isa_slot_offset = (unsigned long)
+		ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024*1024);
 
 	/*
 	 * 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);
+	cmdreg = READCFG32((A_PCI_TYPE01_HEADER | MATCH_BITS) +
+			   PCI_COMMAND);
 
 	if (cmdreg & PCI_COMMAND_MASTER) {
 		sb1250_bus_status |= LDT_BUS_ENABLED;
@@ -271,6 +285,9 @@
 	printk("PCI: Probing PCI hardware on host bus 0.\n");
 	pci_scan_bus(0, &sb1250_pci_ops, NULL);
 
+#ifdef CONFIG_VGA_CONSOLE
+	take_over_console(&vga_con,0,MAX_NR_CONSOLES-1,1);
+#endif
 }
 
 int pcibios_enable_device(struct pci_dev *dev)
@@ -280,7 +297,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-                            unsigned long size)
+		       unsigned long size)
 {
 }
 
@@ -296,7 +313,7 @@
 };
 
 void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			struct resource *res, int resource)
+	struct resource *res, int resource)
 {
 	unsigned long where, size;
 	u32 reg;
@@ -312,7 +329,7 @@
  *  Called after each bus is probed, but before its children
  *  are examined.
  */
-void pcibios_fixup_bus(struct pci_bus *b)
+void __devinit pcibios_fixup_bus(struct pci_bus *b)
 {
 	pci_read_bridge_bases(b);
 }
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/prom.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/prom.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/prom.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/prom.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,119 @@
+/*
+ * 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 <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/blk.h>
+#include <linux/bootmem.h>
+#include <linux/smp.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+
+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
+
+#define MAX_RAM_SIZE ((CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - 1)
+
+static __init void prom_meminit(void)
+{
+#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))) {
+		panic("initrd out of addressable memory");
+	}
+
+	add_memory_region(0, initrd_pstart,
+			  BOOT_MEM_RAM);
+	add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+			  BOOT_MEM_RESERVED);
+	add_memory_region(initrd_pend,
+			  (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - initrd_pend,
+			  BOOT_MEM_RAM);
+#else
+	add_memory_region(0, CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024,
+			  BOOT_MEM_RAM);
+#endif
+}
+
+void prom_cpu0_exit(void *unused)
+{
+        while (1) ;
+}
+
+static void prom_linux_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id()) {
+		smp_call_function(prom_cpu0_exit,NULL,1,1);
+	}
+#endif
+	while(1);
+}
+
+/*
+ * 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)
+{
+	_machine_restart   = (void (*)(char *))prom_linux_exit;
+	_machine_halt      = prom_linux_exit;
+	_machine_power_off = prom_linux_exit;
+
+	strcpy(arcs_cmdline, "root=/dev/ram0 ");
+
+	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 */
+}
+
+int page_is_ram(unsigned long pagenr)
+{
+	phys_t addr = pagenr << PAGE_SHIFT;
+	return (addr < (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024));
+}
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/setup.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/setup.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/setup.c	Thu Sep 12 20:01:40 2002
@@ -10,58 +10,45 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.h>
 #include <asm/sibyte/sb1250_regs.h>
- 
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/64bit.h>
 
-/* 
- *
- */
+/* Setup code likely to be common to all BCM1250 platforms */
 
+unsigned int sb1250_pass;
 
 void sb1250_setup(void)
 {
+	int bad_config = 0;
+
+	sb1250_pass = G_SYS_REVISION(in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION));
+	/* sb1250_pass is more specific than "1", "2" etc.  There are
+           many revision numbers corresponding to "Pass 2". */
+	switch(sb1250_pass) {
+	case 1:
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+		printk("@@@@ This is a pass 1 board, and the kernel doesn't have the proper workarounds compiled in. @@@@");
+		bad_config = 1;
+#endif
+		break;
+	default:
+#if defined(CONFIG_CPU_HAS_PREFETCH) || !defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
+		printk("@@@@ This is a pass 2 board, and the kernel doesn't have the proper workarounds compiled in. @@@@");
+		printk("@@@@ Prefetches are enabled in this kernel, but are buggy on this board.  @@@@");
+		bad_config = 1;
+#endif
+		break;
+	}
+	/* XXXKW this is too early for panic/printk to actually do much! */
+	if (bad_config) {
+		panic("Invalid configuration for this pass.");
+	}
 }
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/smp.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/smp.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/smp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/smp.c	Thu Sep 12 20:01:40 2002
@@ -10,18 +10,24 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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/delay.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
 #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>
+#include <asm/sibyte/sb1250_int.h>
+
+extern void smp_call_function_interrupt(void);
 
 /*
  * These are routines for dealing with the sb1250 smp capabilities
@@ -29,17 +35,17 @@
  */
 
 static u64 mailbox_set_regs[] = {
-	KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU, 
+	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_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_CPU0_BASE + R_IMR_MAILBOX_CPU,
 	KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU
 };
 
@@ -66,7 +72,8 @@
 {
 	int cpu = smp_processor_id();
 	unsigned int action;
-	
+
+	kstat.irqs[cpu][K_INT_MBOX_0]++;
 	/* Load the mailbox register to figure out what we're supposed to do */
 	action = (in64(mailbox_regs[cpu]) >> 48) & 0xffff;
 
@@ -82,3 +89,68 @@
 		smp_call_function_interrupt();
 	}
 }
+
+extern atomic_t cpus_booted;
+extern int prom_setup_smp(void);
+extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+
+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... */
+	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);
+		} while (!retval && (cur_cpu < NR_CPUS));
+		if (retval) {
+			i++;
+		} else {
+			panic("CPU discovery disaster");
+		}
+	}
+
+	/* Wait for everyone to come up */
+	while (atomic_read(&cpus_booted) != smp_num_cpus);
+	smp_threads_ready = 1;
+}
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/sb1250/time.c linux-2.4.20-pre7/arch/mips/sibyte/sb1250/time.c
--- linux-2.4.20-pre6/arch/mips/sibyte/sb1250/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/sb1250/time.c	Thu Sep 12 20:01:40 2002
@@ -10,17 +10,17 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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, 
+ * 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.)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -46,6 +47,8 @@
 #define IMR_IP3_VAL	K_INT_MAP_I1
 #define IMR_IP4_VAL	K_INT_MAP_I2
 
+extern int sb1250_steal_irq(int irq);
+
 void sb1250_time_init(void)
 {
 	int cpu = smp_processor_id();
@@ -55,11 +58,16 @@
 		BUG();
 	}
 
+	if (!cpu) {
+		/* Use our own gettimeoffset() routine */
+		do_gettimeoffset = sb1250_gettimeoffset;
+	}
+
 	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)); 
+	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 */
@@ -77,6 +85,7 @@
 	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
 
 	sb1250_unmask_irq(cpu, K_INT_TIMER_0 + cpu);
+	sb1250_steal_irq(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
@@ -91,9 +100,10 @@
 {
 	int cpu = smp_processor_id();
 
+	kstat.irqs[cpu][K_INT_TIMER_0+cpu]++;
 	/* Reset the timer */
 	out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
-	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));  
+	      KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
 
 	/*
 	 * CPU 0 handles the global timer interrupt job
@@ -107,3 +117,17 @@
 	 */
 	ll_local_timer_interrupt(0, regs);
 }
+
+/*
+ * We use our own do_gettimeoffset() instead of the generic one,
+ * because the generic one does not work for SMP case.
+ * In addition, since we use general timer 0 for system time,
+ * we can get accurate intra-jiffy offset without calibration.
+ */
+unsigned long sb1250_gettimeoffset(void)
+{
+	unsigned long count =
+		in64(KSEG1 + A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT));
+
+	return 1000000/HZ - count;
+ }
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/Makefile linux-2.4.20-pre7/arch/mips/sibyte/swarm/Makefile
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/Makefile	Thu Sep 12 20:01:40 2002
@@ -2,9 +2,7 @@
 
 all: sbswarm.a
 
-OBJS-y                   = setup.o cmdline.o memory.o cfe_api.o rtc_xicor1241.o
-
-OBJS-$(CONFIG_SMP)      += smp.o
+OBJS-y                   = setup.o cmdline.o rtc_xicor1241.o
 
 OBJS-$(CONFIG_L3DEMO)   += procl3switch.o l3procbootstrap.o l3proc.o
 OBJS-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_api.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_api.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_api.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_api.c	Wed Dec 31 16:00:00 1969
@@ -1,402 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_api.h linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_api.h
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_api.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_api.h	Wed Dec 31 16:00:00 1969
@@ -1,61 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_error.h linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_error.h
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_error.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_error.h	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_xiocb.h linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_xiocb.h
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/cfe_xiocb.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/cfe_xiocb.h	Wed Dec 31 16:00:00 1969
@@ -1,179 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/cmdline.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/cmdline.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/cmdline.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/cmdline.c	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/memory.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/memory.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/memory.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/memory.c	Wed Dec 31 16:00:00 1969
@@ -1,48 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/rtc.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/rtc.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/rtc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/rtc.c	Wed Dec 31 16:00:00 1969
@@ -1,44 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/rtc_xicor1241.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/rtc_xicor1241.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/rtc_xicor1241.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/rtc_xicor1241.c	Thu Sep 12 20:01:40 2002
@@ -125,7 +125,7 @@
 	/* 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);
 
@@ -189,7 +189,7 @@
 	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);
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/setup.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/setup.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/setup.c	Thu Sep 12 20:01:40 2002
@@ -10,219 +10,58 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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 
+ * 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 <linux/console.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 <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/64bit.h>
+#include <asm/sibyte/swarm.h>
 
-#include "cfe_xiocb.h"
-#include "cfe_api.h"
-#include "cfe_error.h"
-
-extern int cfe_console_handle;
+extern struct rtc_ops *rtc_ops;
+extern struct rtc_ops swarm_rtc_ops;
 
-#ifdef CONFIG_BLK_DEV_IDE_SWARM
-extern struct ide_ops *ide_ops;
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+#ifdef CONFIG_BLK_DEV_IDE_SIBYTE
+extern struct ide_ops sibyte_ide_ops;
+#endif
 #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
+static unsigned char *led_ptr;
+#define LED_BASE_ADDR (A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, LEDS_CS)))
+#define setled(index, c) led_ptr[(3-((index)&3)) << 3] = (c)
 
 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)
 {
@@ -230,7 +69,7 @@
 
 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.
          */
@@ -240,12 +79,15 @@
 }
 
 extern int xicor_set_time(unsigned long);
-extern unsigned int xicor_get_time(void);
+extern unsigned long xicor_get_time(void);
+extern void sb1250_setup(void);
 
 void __init swarm_setup(void)
 {
 	extern int panic_timeout;
 
+	sb1250_setup();
+
 	panic_timeout = 5;  /* For debug.  */
 
         board_timer_setup = swarm_timer_setup;
@@ -253,10 +95,6 @@
         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");
@@ -268,231 +106,58 @@
 #else
 	       "board"
 #endif
-	       " runs\n");
-
-#ifdef CONFIG_BLK_DEV_IDE_SWARM
-	ide_ops = &swarm_ide_ops;
+	       " runs "
+#ifdef CONFIG_SIBYTE_CFE
+	       "with"
+#else
+	       "without"
 #endif
-}  
+	       " CFE\n");
 
-/* 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;  
+#ifdef CONFIG_BLK_DEV_IDE
+#ifdef CONFIG_BLK_DEV_IDE_SIBYTE
+	ide_ops = &sibyte_ide_ops;
+#else
+	ide_ops = &std_ide_ops;
 #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);
-	}
+	/* Set up the LED base address */
+#ifdef __MIPSEL__
+	/* Pass1 workaround (bug 1624) */
+	if (sb1250_pass == K_SYS_REVISION_PASS1)
+		led_ptr = (unsigned char *)
+			((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(4+(KSEG1|LED_BASE_ADDR))) << S_IO_ADDRBASE))+0x20);
+	else
+#endif
+		led_ptr = (unsigned char *)
+			((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(KSEG1|LED_BASE_ADDR)) << S_IO_ADDRBASE))+0x20);
+
+#ifdef CONFIG_VT
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+	screen_info = (struct screen_info) {
+		0, 0,           /* orig-x, orig-y */
+		0,              /* unused */
+		52,             /* orig_video_page */
+		3,              /* orig_video_mode */
+		80,             /* orig_video_cols */
+		4626, 3, 9,     /* unused, ega_bx, unused */
+		25,             /* orig_video_lines */
+		0x22,           /* orig_video_isVGA */
+		16              /* orig_video_points */
+       };
+       /* XXXKW for CFE, get lines/cols from environment */
 #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++) { 
+			for (; i < 4; i++) {
 				setled(' ', str[i]);
 			}
 		} else {
@@ -516,27 +181,27 @@
 	setleds("    ");
 }
 
-static void move_leds(unsigned long arg) 
+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; 
+		if (!*tmp) {
+			tmp = led_msg;
 		}
 	}
 	led_msg_ptr++;
-	if (!*led_msg_ptr) { 
- 		led_msg_ptr = led_msg; 
+	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) 
+void hack_leds(void)
 {
 	init_timer(&led_timer);
 	led_timer.expires = jiffies + (HZ/8);
diff -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/smp.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/smp.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/smp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/smp.c	Wed Dec 31 16:00:00 1969
@@ -1,182 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/sibyte/swarm/time.c linux-2.4.20-pre7/arch/mips/sibyte/swarm/time.c
--- linux-2.4.20-pre6/arch/mips/sibyte/swarm/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/sibyte/swarm/time.c	Wed Dec 31 16:00:00 1969
@@ -1,241 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/arch/mips/tools/Makefile linux-2.4.20-pre7/arch/mips/tools/Makefile
--- linux-2.4.20-pre6/arch/mips/tools/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/tools/Makefile	Thu Sep 12 20:01:40 2002
@@ -17,9 +17,8 @@
 
 clean:
 	rm -f offset.[hs] $(TARGET).new
-	
-mrproper:	
-	rm -f offset.[hs] $(TARGET).new
+
+mrproper: clean
 	rm -f $(TARGET)
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/tools/offset.c linux-2.4.20-pre7/arch/mips/tools/offset.c
--- linux-2.4.20-pre6/arch/mips/tools/offset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips/tools/offset.c	Thu Sep 12 20:01:40 2002
@@ -2,8 +2,8 @@
  * offset.c: Calculate pt_regs and task_struct offsets.
  *
  * Copyright (C) 1996 David S. Miller
- * Copyright (C) 1997, 1998, 1999 Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  *
  * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.
@@ -82,15 +82,16 @@
 	text("/* MIPS task_struct offsets. */");
 	offset("#define TASK_STATE         ", struct task_struct, state);
 	offset("#define TASK_FLAGS         ", struct task_struct, flags);
+	constant("  #define _PT_TRACESYS        ", PT_TRACESYS);
 	offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
 	offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
 	offset("#define TASK_PTRACE        ", struct task_struct, ptrace);
 	offset("#define TASK_COUNTER       ", struct task_struct, counter);
 	offset("#define TASK_NICE          ", struct task_struct, nice);
 	offset("#define TASK_MM            ", struct task_struct, mm);
+	offset("#define TASK_PROCESSOR     ", struct task_struct, processor);
 	offset("#define TASK_PID           ", struct task_struct, pid);
 	size(  "#define TASK_STRUCT_SIZE   ", struct task_struct);
-	constant("#define PT_TRACESYS        ", PT_TRACESYS);
 	linefeed;
 }
 
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/Makefile linux-2.4.20-pre7/arch/mips/vr41xx/common/Makefile
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,21 @@
+#
+# Makefile for common code of the NEC VR4100 series.
+#
+# 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: vr41xx.o
+
+O_TARGET := vr41xx.o
+
+obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o
+
+obj-$(CONFIG_PCI)		+= pciu.o
+obj-$(CONFIG_SERIAL)		+= serial.o
+obj-$(CONFIG_VR41XX_TIME_C)	+= time.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/bcu.c linux-2.4.20-pre7/arch/mips/vr41xx/common/bcu.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/bcu.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/bcu.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,206 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/bcu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Bus Control Unit routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - Calculate mips_counter_frequency properly on VR4131.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define VR4111_CLKSPEEDREG	KSEG1ADDR(0x0b000014)
+#define VR4122_CLKSPEEDREG	KSEG1ADDR(0x0f000014)
+#define VR4131_CLKSPEEDREG	VR4122_CLKSPEEDREG
+ #define CLKSP(x)		((x) & 0x001f)
+
+ #define DIV2B			0x8000
+ #define DIV3B			0x4000
+ #define DIV4B			0x2000
+
+ #define DIVT(x)		(((x) & 0xf000) >> 12)
+ #define DIVVT(x)		(((x) & 0x0f00) >> 8)
+
+ #define TDIVMODE(x)		(2 << (((x) & 0x1000) >> 12))
+ #define VTDIVMODE(x)		(((x) & 0x0700) >> 8)
+
+unsigned long vr41xx_vtclock = 0;
+
+static inline u16 read_clkspeed(void)
+{
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121: return readw(VR4111_CLKSPEEDREG);
+	case CPU_VR4122: return readw(VR4122_CLKSPEEDREG);
+	case CPU_VR4131: return readw(VR4131_CLKSPEEDREG);
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	return 0;
+}
+
+static inline unsigned long calculate_pclock(u16 clkspeed)
+{
+	unsigned long pclock = 0;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		pclock = 18432000 * 64;
+		break;
+	case CPU_VR4122:
+		pclock = 18432000 * 98;
+		break;
+	case CPU_VR4131:
+		pclock = 18432000 * 108;
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	pclock /= CLKSP(clkspeed);
+	printk(KERN_INFO "PClock: %ldHz\n", pclock);
+
+	return pclock;
+}
+
+static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock)
+{
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+		/* The NEC VR4111 doesn't have the VTClock. */
+		break;
+	case CPU_VR4121:
+		vr41xx_vtclock = pclock;
+		/* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
+		if (DIVVT(clkspeed) == 9)
+			vr41xx_vtclock = pclock * 6;
+		/* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
+		else if (DIVVT(clkspeed) == 10)
+			vr41xx_vtclock = pclock * 4;
+		vr41xx_vtclock /= DIVVT(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		break;
+	case CPU_VR4122:
+		if(VTDIVMODE(clkspeed) == 7)
+			vr41xx_vtclock = pclock / 1;
+		else if(VTDIVMODE(clkspeed) == 1)
+			vr41xx_vtclock = pclock / 2;
+		else
+			vr41xx_vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		break;
+	case CPU_VR4131:
+		vr41xx_vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	return vr41xx_vtclock;
+}
+
+static inline unsigned long calculate_tclock(u16 clkspeed, unsigned long pclock,
+                                             unsigned long vtclock)
+{
+	unsigned long tclock = 0;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+		if (!(clkspeed & DIV2B))
+        		tclock = pclock / 2;
+		else if (!(clkspeed & DIV3B))
+        		tclock = pclock / 3;
+		else if (!(clkspeed & DIV4B))
+        		tclock = pclock / 4;
+		break;
+	case CPU_VR4121:
+		tclock = pclock / DIVT(clkspeed);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		tclock = vtclock / TDIVMODE(clkspeed);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+
+	printk(KERN_INFO "TClock: %ldHz\n", tclock);
+
+	return tclock;
+}
+
+static inline unsigned long calculate_mips_counter_frequency(unsigned long tclock)
+{
+	/*
+	 * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2).
+	 */
+	if ((mips_cpu.processor_id == PRID_VR4131_REV2_0) ||
+	    (mips_cpu.processor_id == PRID_VR4131_REV2_1))
+		tclock /= 2;
+	else
+		tclock /= 4;
+
+	return tclock;
+}
+
+void __init vr41xx_bcu_init(void)
+{
+	unsigned long pclock, vtclock, tclock;
+	u16 clkspeed;
+
+	clkspeed = read_clkspeed();
+
+	pclock = calculate_pclock(clkspeed);
+	vtclock = calculate_vtclock(clkspeed, pclock);
+	tclock = calculate_tclock(clkspeed, pclock, vtclock);
+
+	mips_counter_frequency = calculate_mips_counter_frequency(tclock);
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/cmu.c linux-2.4.20-pre7/arch/mips/vr41xx/common/cmu.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/cmu.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/cmu.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,84 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/cmu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Clock Mask Unit routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+
+#define VR4111_CMUCLKMSK	KSEG1ADDR(0x0b000060)
+#define VR4122_CMUCLKMSK	KSEG1ADDR(0x0f000060)
+
+static u32 vr41xx_cmu_base;
+static u16 cmuclkmsk;
+
+#define write_cmu(mask)	writew((mask), vr41xx_cmu_base)
+
+void vr41xx_clock_supply(u16 mask)
+{
+	cmuclkmsk |= mask;
+	write_cmu(cmuclkmsk);
+}
+
+void vr41xx_clock_mask(u16 mask)
+{
+	cmuclkmsk &= ~mask;
+	write_cmu(cmuclkmsk);
+}
+
+void __init vr41xx_cmu_init(u16 mask)
+{
+	switch (mips_cpu.cputype) {
+        case CPU_VR4111:
+        case CPU_VR4121:
+                vr41xx_cmu_base = VR4111_CMUCLKMSK;
+                break;
+        case CPU_VR4122:
+        case CPU_VR4131:
+                vr41xx_cmu_base = VR4122_CMUCLKMSK;
+                break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+        }
+
+	cmuclkmsk = mask;
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/giu.c linux-2.4.20-pre7/arch/mips/vr41xx/common/giu.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/giu.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/giu.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,270 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/giu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	General-purpose I/O Unit Interrupt routines for NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define VR4111_GIUIOSELL	KSEG1ADDR(0x0b000100)
+#define VR4122_GIUIOSELL	KSEG1ADDR(0x0f000140)
+
+#define GIUIOSELL	0x00
+#define GIUIOSELH	0x02
+#define GIUINTSTATL	0x08
+#define GIUINTSTATH	0x0a
+#define GIUINTENL	0x0c
+#define GIUINTENH	0x0e
+#define GIUINTTYPL	0x10
+#define GIUINTTYPH	0x12
+#define GIUINTALSELL	0x14
+#define GIUINTALSELH	0x16
+#define GIUINTHTSELL	0x18
+#define GIUINTHTSELH	0x1a
+
+u32 vr41xx_giu_base = 0;
+
+#define read_giuint(offset)		readw(vr41xx_giu_base + (offset))
+#define write_giuint(val, offset)	writew((val), vr41xx_giu_base + (offset))
+
+static inline u16 set_giuint(u16 offset, u16 set)
+{
+	u16 res;
+
+	res = read_giuint(offset);
+	res |= set;
+	write_giuint(res, offset);
+
+	return res;
+}
+
+static inline u16 clear_giuint(u16 offset, u16 clear)
+{
+	u16 res;
+
+	res = read_giuint(offset);
+	res &= ~clear;
+	write_giuint(res, offset);
+
+	return res;
+}
+
+void vr41xx_enable_giuint(u8 pin)
+{
+	if (pin < 16)
+		set_giuint(GIUINTENL, (u16)1 << pin);
+	else
+		set_giuint(GIUINTENH, (u16)1 << (pin - 16));
+}
+
+void vr41xx_disable_giuint(u8 pin)
+{
+	if (pin < 16)
+		clear_giuint(GIUINTENL, (u16)1 << pin);
+	else
+		clear_giuint(GIUINTENH, (u16)1 << (pin - 16));
+}
+
+void vr41xx_clear_giuint(u8 pin)
+{
+	if (pin < 16)
+		write_giuint(GIUINTSTATL, (u16)1 << pin);
+	else
+		write_giuint(GIUINTSTATH, (u16)1 << (pin - 16));
+}
+
+void vr41xx_set_irq_trigger(u8 pin, u8 trigger, u8 hold)
+{
+	u16 mask;
+
+	if (pin < 16) {
+		mask = (u16)1 << pin;
+		if (trigger == TRIGGER_EDGE) {
+        		set_giuint(GIUINTTYPL, mask);
+			if (hold == SIGNAL_HOLD)
+				set_giuint(GIUINTHTSELL, mask);
+			else
+				clear_giuint(GIUINTHTSELL, mask);
+		} else {
+			clear_giuint(GIUINTTYPL, mask);
+			clear_giuint(GIUINTHTSELL, mask);
+		}
+	} else {
+		mask = (u16)1 << (pin - 16);
+		if (trigger == TRIGGER_EDGE) {
+			set_giuint(GIUINTTYPH, mask);
+			if (hold == SIGNAL_HOLD)
+				set_giuint(GIUINTHTSELH, mask);
+			else
+				clear_giuint(GIUINTHTSELH, mask);
+		} else {
+			clear_giuint(GIUINTTYPH, mask);
+			clear_giuint(GIUINTHTSELH, mask);
+		}
+	}
+
+	vr41xx_clear_giuint(pin);
+}
+
+void vr41xx_set_irq_level(u8 pin, u8 level)
+{
+	u16 mask;
+
+	if (pin < 16) {
+		mask = (u16)1 << pin;
+		if (level == LEVEL_HIGH)
+			set_giuint(GIUINTALSELL, mask);
+		else
+			clear_giuint(GIUINTALSELL, mask);
+	} else {
+		mask = (u16)1 << (pin - 16);
+		if (level == LEVEL_HIGH)
+			set_giuint(GIUINTALSELH, mask);
+		else
+			clear_giuint(GIUINTALSELH, mask);
+	}
+
+	vr41xx_clear_giuint(pin);
+}
+
+#define GIUINT_CASCADE_IRQ	16
+#define GIUINT_NR_IRQS		32
+
+enum {
+	GIUINT_NO_CASCADE,
+	GIUINT_CASCADE
+};
+
+struct vr41xx_giuint_cascade {
+	unsigned int flag;
+	int (*get_irq_number)(int irq);
+};
+
+static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS];
+static struct irqaction giu_cascade = {no_action, 0, 0, "cascade", NULL, NULL};
+
+static int no_irq_number(int irq)
+{
+	return -EINVAL;
+}
+
+int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq))
+{
+	unsigned int pin;
+	int retval;
+
+	if (irq < GIU_IRQ(0) || irq > GIU_IRQ(31))
+		return -EINVAL;
+
+	if(!get_irq_number)
+		return -EINVAL;
+
+	pin = irq - GIU_IRQ(0);
+	giuint_cascade[pin].flag = GIUINT_CASCADE;
+	giuint_cascade[pin].get_irq_number = get_irq_number;
+
+	retval = setup_irq(irq, &giu_cascade);
+	if (retval) {
+		giuint_cascade[pin].flag = GIUINT_NO_CASCADE;
+		giuint_cascade[pin].get_irq_number = no_irq_number;
+	}
+
+	return retval;
+}
+
+extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs)
+{
+	struct vr41xx_giuint_cascade *cascade;
+	unsigned int retval = 0;
+	int giuint_irq, cascade_irq;
+
+	disable_irq(GIUINT_CASCADE_IRQ);
+	cascade = &giuint_cascade[pin];
+	giuint_irq = pin + GIU_IRQ(0);
+	if (cascade->flag == GIUINT_CASCADE) {
+		cascade_irq = cascade->get_irq_number(giuint_irq);
+		disable_irq(giuint_irq);
+		if (cascade_irq > 0)
+			retval = do_IRQ(cascade_irq, regs);
+		enable_irq(giuint_irq);
+	} else
+		retval = do_IRQ(giuint_irq, regs);
+	enable_irq(GIUINT_CASCADE_IRQ);
+
+	return retval;
+}
+
+void (*board_irq_init)(void) = NULL;
+
+void __init vr41xx_giuint_init(void)
+{
+	int i;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		vr41xx_giu_base = VR4111_GIUIOSELL;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		vr41xx_giu_base = VR4122_GIUIOSELL;
+		break;
+	default:
+		panic("GIU: Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+
+	for (i = 0; i < GIUINT_NR_IRQS; i++) {
+                vr41xx_disable_giuint(i);
+		giuint_cascade[i].flag = GIUINT_NO_CASCADE;
+		giuint_cascade[i].get_irq_number = no_irq_number;
+	}
+
+	if (setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade))
+		printk("GIUINT: Can not cascade IRQ %d.\n", GIUINT_CASCADE_IRQ);
+
+	if (board_irq_init)
+		board_irq_init();
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/icu.c linux-2.4.20-pre7/arch/mips/vr41xx/common/icu.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/icu.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/icu.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,422 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/vr4122/common/icu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt Control Unit routines for the NEC VR4122 and VR4131.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - kgdb support.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/gdb-stub.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define MIPS_CPU_IRQ_BASE	0
+#define SYSINT1_IRQ_BASE	8
+#define SYSINT1_IRQ_LAST	23
+#define SYSINT2_IRQ_BASE	24
+#define SYSINT2_IRQ_LAST	39
+#define GIUINT_IRQ_BASE		GIU_IRQ(0)
+#define GIUINT_IRQ_LAST		GIU_IRQ(31)
+
+#define ICU_CASCADE_IRQ		(MIPS_CPU_IRQ_BASE + 2)
+
+extern asmlinkage void vr41xx_handle_interrupt(void);
+
+extern void __init init_generic_irq(void);
+extern void mips_cpu_irq_init(u32 irq_base);
+extern unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+extern void vr41xx_giuint_init(void);
+extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs);
+
+static u32 vr41xx_icu1_base = 0;
+static u32 vr41xx_icu2_base = 0;
+
+#define VR4111_SYSINT1REG	KSEG1ADDR(0x0b000080)
+#define VR4111_SYSINT2REG	KSEG1ADDR(0x0b000200)
+
+#define VR4122_SYSINT1REG	KSEG1ADDR(0x0f000080)
+#define VR4122_SYSINT2REG	KSEG1ADDR(0x0f0000a0)
+
+#define SYSINT1REG	0x00
+#define GIUINTLREG	0x08
+#define MSYSINT1REG	0x0c
+#define MGIUINTLREG	0x14
+#define NMIREG		0x18
+#define SOFTREG		0x1a
+
+#define SYSINT2REG	0x00
+#define GIUINTHREG	0x02
+#define MSYSINT2REG	0x06
+#define MGIUINTHREG	0x08
+
+#define read_icu1(offset)	readw(vr41xx_icu1_base + (offset))
+#define write_icu1(val, offset)	writew((val), vr41xx_icu1_base + (offset))
+
+#define read_icu2(offset)	readw(vr41xx_icu2_base + (offset))
+#define write_icu2(val, offset)	writew((val), vr41xx_icu2_base + (offset))
+
+static inline u16 set_icu1(u16 offset, u16 set)
+{
+	u16 res;
+
+	res = read_icu1(offset);
+	res |= set;
+	write_icu1(res, offset);
+
+	return res;
+}
+
+static inline u16 clear_icu1(u16 offset, u16 clear)
+{
+	u16 res;
+
+	res = read_icu1(offset);
+	res &= ~clear;
+	write_icu1(res, offset);
+
+	return res;
+}
+
+static inline u16 set_icu2(u16 offset, u16 set)
+{
+	u16 res;
+
+	res = read_icu2(offset);
+	res |= set;
+	write_icu2(res, offset);
+
+	return res;
+}
+
+static inline u16 clear_icu2(u16 offset, u16 clear)
+{
+	u16 res;
+
+	res = read_icu2(offset);
+	res &= ~clear;
+	write_icu2(res, offset);
+
+	return res;
+}
+
+/*=======================================================================*/
+
+static void enable_sysint1_irq(unsigned int irq)
+{
+	set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+}
+
+static void disable_sysint1_irq(unsigned int irq)
+{
+	clear_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+}
+
+static unsigned int startup_sysint1_irq(unsigned int irq)
+{
+	set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sysint1_irq	disable_sysint1_irq
+#define ack_sysint1_irq		disable_sysint1_irq
+
+static void end_sysint1_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+}
+
+static struct hw_interrupt_type sysint1_irq_type = {
+	"SYSINT1",
+	startup_sysint1_irq,
+	shutdown_sysint1_irq,
+	enable_sysint1_irq,
+	disable_sysint1_irq,
+	ack_sysint1_irq,
+	end_sysint1_irq,
+	NULL
+};
+
+/*=======================================================================*/
+
+static void enable_sysint2_irq(unsigned int irq)
+{
+	set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+}
+
+static void disable_sysint2_irq(unsigned int irq)
+{
+	clear_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+}
+
+static unsigned int startup_sysint2_irq(unsigned int irq)
+{
+	set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sysint2_irq	disable_sysint2_irq
+#define ack_sysint2_irq		disable_sysint2_irq
+
+static void end_sysint2_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+}
+
+static struct hw_interrupt_type sysint2_irq_type = {
+	"SYSINT2",
+	startup_sysint2_irq,
+	shutdown_sysint2_irq,
+	enable_sysint2_irq,
+	disable_sysint2_irq,
+	ack_sysint2_irq,
+	end_sysint2_irq,
+	NULL
+};
+
+/*=======================================================================*/
+
+extern void vr41xx_enable_giuint(u8 pin);
+extern void vr41xx_disable_giuint(u8 pin);
+extern void vr41xx_clear_giuint(u8 pin);
+
+static void enable_giuint_irq(unsigned int irq)
+{
+	u8 pin;
+
+	pin = irq - GIUINT_IRQ_BASE;
+	if (pin < 16)
+		set_icu1(MGIUINTLREG, (u16)1 << pin);
+	else
+		set_icu2(MGIUINTHREG, (u16)1 << (pin - 16));
+
+	vr41xx_enable_giuint(pin);
+}
+
+static void disable_giuint_irq(unsigned int irq)
+{
+	u8 pin;
+
+	pin = irq - GIUINT_IRQ_BASE;
+	vr41xx_disable_giuint(pin);
+
+	if (pin < 16)
+		clear_icu1(MGIUINTLREG, (u16)1 << pin);
+	else
+		clear_icu2(MGIUINTHREG, (u16)1 << (pin - 16));
+}
+
+static unsigned int startup_giuint_irq(unsigned int irq)
+{
+	vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE);
+
+	enable_giuint_irq(irq);
+
+	return 0; /* never anything pending */
+}
+
+#define shutdown_giuint_irq	disable_giuint_irq
+
+static void ack_giuint_irq(unsigned int irq)
+{
+	disable_giuint_irq(irq);
+
+	vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE);
+}
+
+static void end_giuint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_giuint_irq(irq);
+}
+
+static struct hw_interrupt_type giuint_irq_type = {
+	"GIUINT",
+	startup_giuint_irq,
+	shutdown_giuint_irq,
+	enable_giuint_irq,
+	disable_giuint_irq,
+	ack_giuint_irq,
+	end_giuint_irq,
+	NULL
+};
+
+/*=======================================================================*/
+
+static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL};
+
+static void __init vr41xx_icu_init(void)
+{
+	int i;
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		vr41xx_icu1_base = VR4111_SYSINT1REG;
+		vr41xx_icu2_base = VR4111_SYSINT2REG;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		vr41xx_icu1_base = VR4122_SYSINT1REG;
+		vr41xx_icu2_base = VR4122_SYSINT2REG;
+		break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+
+	write_icu1(0, MSYSINT1REG);
+	write_icu1(0, MGIUINTLREG);
+
+	write_icu2(0, MSYSINT2REG);
+	write_icu2(0, MGIUINTHREG);
+
+	for (i = SYSINT1_IRQ_BASE; i <= GIUINT_IRQ_LAST; i++) {
+		if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST)
+			irq_desc[i].handler = &sysint1_irq_type;
+		else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST)
+			irq_desc[i].handler = &sysint2_irq_type;
+		else if (i >= GIUINT_IRQ_BASE && i <= GIUINT_IRQ_LAST)
+			irq_desc[i].handler = &giuint_irq_type;
+	}
+
+	setup_irq(ICU_CASCADE_IRQ, &icu_cascade);
+}
+
+void __init init_IRQ(void)
+{
+	memset(irq_desc, 0, sizeof(irq_desc));
+
+	init_generic_irq();
+	mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
+	vr41xx_icu_init();
+
+	vr41xx_giuint_init();
+
+	set_except_vector(0, vr41xx_handle_interrupt);
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("Setting debug traps - please connect the remote debugger.\n");
+	set_debug_traps();
+	breakpoint();
+#endif
+}
+
+/*=======================================================================*/
+
+static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs)
+{
+	int i;
+
+	if (pendl) {
+		for (i = 0; i < 16; i++) {
+			if (pendl & (0x0001 << i)) {
+				giuint_do_IRQ(i, regs);
+				return;
+			}
+		}
+	}
+	else if (pendh) {
+		for (i = 0; i < 16; i++) {
+			if (pendh & (0x0001 << i)) {
+				giuint_do_IRQ(i + 16, regs);
+				return;
+			}
+		}
+	}
+}
+
+asmlinkage void icu_irqdispatch(struct pt_regs *regs)
+{
+	u16 pend1, pend2, pendl, pendh;
+	u16 mask1, mask2, maskl, maskh;
+	int i;
+
+	pend1 = read_icu1(SYSINT1REG);
+	mask1 = read_icu1(MSYSINT1REG);
+
+	pend2 = read_icu2(SYSINT2REG);
+	mask2 = read_icu2(MSYSINT2REG);
+
+	pendl = read_icu1(GIUINTLREG);
+	maskl = read_icu1(MGIUINTLREG);
+
+	pendh = read_icu2(GIUINTHREG);
+	maskh = read_icu2(MGIUINTHREG);
+
+	pend1 &= mask1;
+	pend2 &= mask2;
+	pendl &= maskl;
+	pendh &= maskh;
+
+	if (pend1) {
+		if ((pend1 & 0x01ff) == 0x0100) {
+			giuint_irqdispatch(pendl, pendh, regs);
+		}
+		else {
+			for (i = 0; i < 16; i++) {
+				if (pend1 & (0x0001 << i)) {
+					do_IRQ(SYSINT1_IRQ_BASE + i, regs);
+					break;
+				}
+			}
+		}
+		return;
+	}
+	else if (pend2) {
+		for (i = 0; i < 16; i++) {
+			if (pend2 & (0x0001 << i)) {
+				do_IRQ(SYSINT2_IRQ_BASE + i, regs);
+				break;
+			}
+		}
+	}
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/int-handler.S linux-2.4.20-pre7/arch/mips/vr41xx/common/int-handler.S
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/int-handler.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/int-handler.S	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,114 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/int-handler.S
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt dispatcher for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4100 series are supported.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+		.text
+		.set	noreorder
+
+		.align	5
+		NESTED(vr41xx_handle_interrupt, PT_SIZE, ra)
+		.set	noat
+		SAVE_ALL
+		CLI
+		.set	at
+		.set	noreorder
+
+		/*
+		 * Get the pending interrupts
+		 */
+		mfc0	t0, CP0_CAUSE
+		mfc0	t1, CP0_STATUS
+		andi	t0, 0xff00
+		and	t0, t0, t1
+
+		andi	t1, t0, CAUSEF_IP7	# timer interrupt
+		beqz	t1, 1f
+		li	a0, 7
+		jal	ll_timer_interrupt
+		move	a1, sp
+		j	ret_from_irq
+
+1:
+		andi	t1, t0, 0x7800		# check for IP3-6
+		beqz	t1, 2f
+
+		andi	t1, t0, CAUSEF_IP3	# check for IP3
+		bnez	t1, handle_it
+		li	a0, 3
+
+		andi	t1, t0, CAUSEF_IP4	# check for IP4
+		bnez	t1, handle_it
+		li	a0, 4
+
+		andi	t1, t0, CAUSEF_IP5	# check for IP5
+		bnez	t1, handle_it
+		li	a0, 5
+
+		andi	t1, t0, CAUSEF_IP6	# check for IP6
+		bnez	t1, handle_it
+		li	a0, 6
+
+2:
+		andi	t1, t0, CAUSEF_IP2	# check for IP2
+		beqz	t1, 3f
+		move	a0, sp
+		jal	icu_irqdispatch
+		nop
+		j	ret_from_irq
+		nop
+
+3:
+		andi	t1, t0, CAUSEF_IP0	# check for IP0
+		bnez	t1, handle_it
+		li	a0, 0
+
+		andi	t1, t0, CAUSEF_IP1	# check for IP1
+		bnez	t1, handle_it
+		li	a0, 1
+
+		j	spurious_interrupt
+		nop
+
+handle_it:
+		jal	do_IRQ
+		move	a1, sp
+		j	ret_from_irq
+		END(vr41xx_handle_interrupt)
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/pciu.c linux-2.4.20-pre7/arch/mips/vr41xx/common/pciu.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/pciu.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/pciu.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,280 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/pciu.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	PCI Control Unit routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - Fix deadlock-causing PCIU access race for VR4131.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/pci_channel.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#include "pciu.h"
+
+extern unsigned long vr41xx_vtclock;
+
+static inline int vr41xx_pci_config_access(struct pci_dev *dev, int where)
+{
+	unsigned char bus = dev->bus->number;
+	unsigned int dev_fn = dev->devfn;
+
+	if (bus == 0) {
+		/*
+		 * Type 0 configuration
+		 */
+		if (PCI_SLOT(dev_fn) < 11 || PCI_SLOT(dev_fn) > 31 || where > 255)
+			return -1;
+
+		writel((1UL << PCI_SLOT(dev_fn))|
+		       (PCI_FUNC(dev_fn) << 8)	|
+		       (where & 0xfc),
+		       PCICONFAREG);
+	}
+	else {
+		/*
+		 * Type 1 configuration
+		 */
+		if (bus > 255 || PCI_SLOT(dev_fn) > 31 || where > 255)
+			return -1;
+
+		writel((bus << 16)	|
+		       (dev_fn << 8)	|
+		       (where & 0xfc)	|
+		       1UL,
+		       PCICONFAREG);
+	}
+
+	return 0;
+}
+
+static int vr41xx_pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+{
+	u32 data;
+
+	*val = 0xff;
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	*val = (u8)(data >> ((where & 3) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int vr41xx_pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
+{
+	u32 data;
+
+	*val = 0xffff;
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	*val = (u16)(data >> ((where & 2) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+{
+	*val = 0xffffffff;
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*val = readl(PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
+{
+	u32 data;
+	int shift;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	shift = (where & 3) << 3;
+	data &= ~(0xff << shift);
+	data |= (((u32)val) << shift);
+
+	writel(data, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
+{
+	u32 data;
+	int shift;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	data = readl(PCICONFDREG);
+	shift = (where & 2) << 3;
+	data &= ~(0xffff << shift);
+	data |= (((u32)val) << shift);
+	writel(data, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int vr41xx_pci_write_config_dword(struct pci_dev *dev, int where, u32 val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	if (vr41xx_pci_config_access(dev, where) < 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	writel(val, PCICONFDREG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops vr41xx_pci_ops = {
+	vr41xx_pci_read_config_byte,
+	vr41xx_pci_read_config_word,
+	vr41xx_pci_read_config_dword,
+	vr41xx_pci_write_config_byte,
+	vr41xx_pci_write_config_word,
+	vr41xx_pci_write_config_dword
+};
+
+void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map)
+{
+	struct vr41xx_pci_address_space *s;
+	u32 config;
+	int n;
+
+	if (!map)
+		return;
+
+	/* Disable PCI interrupt */
+	writew(0, MPCIINTREG);
+
+	/* Supply VTClock to PCIU */
+	vr41xx_clock_supply(PCIU_CLOCK);
+
+	/*
+	 * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK
+	 * before doing any PCIU access to avoid deadlock on VR4131.
+	 */
+	udelay(1);
+
+	/* Select PCI clock */
+	if (vr41xx_vtclock < MAX_PCI_CLOCK)
+		writel(EQUAL_VTCLOCK, PCICLKSELREG);
+	else if ((vr41xx_vtclock / 2) < MAX_PCI_CLOCK)
+		writel(HALF_VTCLOCK, PCICLKSELREG);
+	else if ((vr41xx_vtclock / 4) < MAX_PCI_CLOCK)
+		writel(QUARTER_VTCLOCK, PCICLKSELREG);
+	else
+		printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n");
+
+	/* Supply PCI clock by PCI bus */
+	vr41xx_clock_supply(PCI_CLOCK);
+
+	/*
+	 * Set PCI memory & I/O space address conversion registers
+	 * for master transaction.
+	 */
+	if (map->mem1 != NULL) {
+		s = map->mem1;
+		config = (s->internal_base & 0xff000000) |
+		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
+		         ((s->pci_base & 0xff000000) >> 24);
+		writel(config, PCIMMAW1REG);
+	}
+	if (map->mem2 != NULL) {
+		s = map->mem2;
+		config = (s->internal_base & 0xff000000) |
+		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
+		         ((s->pci_base & 0xff000000) >> 24);
+		writel(config, PCIMMAW2REG);
+	}
+	if (map->io != NULL) {
+		s = map->io;
+		config = (s->internal_base & 0xff000000) |
+		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
+		         ((s->pci_base & 0xff000000) >> 24);
+		writel(config, PCIMIOAWREG);
+	}
+
+	/* Set target memory windows */
+	writel(0x00081000, PCITAW1REG);
+	writel(0UL, PCITAW2REG);
+	pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL);
+	pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL);
+
+	/* Clear bus error */
+	n = readl(BUSERRADREG);
+
+	if (mips_cpu.cputype == CPU_VR4122) {
+		writel(0UL, PCITRDYVREG);
+		pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804);
+	} else {
+		writel(100UL, PCITRDYVREG);
+		pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004);
+	}
+
+	writel(CONFIG_DONE, PCIENREG);
+	pciu_write_config_dword(PCI_COMMAND,
+	                        PCI_COMMAND_IO |
+	                        PCI_COMMAND_MEMORY |
+	                        PCI_COMMAND_MASTER |
+	                        PCI_COMMAND_PARITY |
+	                        PCI_COMMAND_SERR);
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/pciu.h linux-2.4.20-pre7/arch/mips/vr41xx/common/pciu.h
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/pciu.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/pciu.h	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,167 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/pciu.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for PCI Control Unit of the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#ifndef __VR41XX_PCIU_H
+#define __VR41XX_PCIU_H
+
+#include <linux/config.h>
+#include <asm/addrspace.h>
+
+#define BIT(x)	(1 << (x))
+
+#define PCIMMAW1REG			KSEG1ADDR(0x0f000c00)
+#define PCIMMAW2REG			KSEG1ADDR(0x0f000c04)
+#define PCITAW1REG			KSEG1ADDR(0x0f000c08)
+#define PCITAW2REG			KSEG1ADDR(0x0f000c0c)
+#define PCIMIOAWREG			KSEG1ADDR(0x0f000c10)
+#define INTERNAL_BUS_BASE_ADDRESS	0xff000000
+#define ADDRESS_MASK			0x000fe000
+#define PCI_ACCESS_ENABLE		BIT(12)
+#define PCI_ADDRESS_SETTING		0x000000ff
+
+#define PCICONFDREG			KSEG1ADDR(0x0f000c14)
+#define PCICONFAREG			KSEG1ADDR(0x0f000c18)
+#define PCIMAILREG			KSEG1ADDR(0x0f000c1c)
+
+#define BUSERRADREG			KSEG1ADDR(0x0f000c24)
+#define ERROR_ADDRESS			0xfffffffc
+
+#define INTCNTSTAREG			KSEG1ADDR(0x0f000c28)
+#define MABTCLR				BIT(31)
+#define TRDYCLR				BIT(30)
+#define PARCLR				BIT(29)
+#define MBCLR				BIT(28)
+#define SERRCLR				BIT(27)
+
+#define PCIEXACCREG			KSEG1ADDR(0x0f000c2c)
+#define UNLOCK				BIT(1)
+#define EAREQ				BIT(0)
+
+#define PCIRECONTREG			KSEG1ADDR(0x0f000c30)
+#define RTRYCNT				0x000000ff
+
+#define PCIENREG			KSEG1ADDR(0x0f000c34)
+#define CONFIG_DONE			BIT(2)
+
+#define PCICLKSELREG			KSEG1ADDR(0x0f000c38)
+#define EQUAL_VTCLOCK			0x00000002
+#define HALF_VTCLOCK			0x00000000
+#define QUARTER_VTCLOCK			0x00000001
+
+#define PCITRDYVREG			KSEG1ADDR(0x0f000c3c)
+
+#define PCICLKRUNREG			KSEG1ADDR(0x0f000c60)
+
+#define PCIU_CONFIGREGS_BASE		KSEG1ADDR(0x0f000d00)
+#define VENDORIDREG			KSEG1ADDR(0x0f000d00)
+#define DEVICEIDREG			KSEG1ADDR(0x0f000d00)
+#define COMMANDREG			KSEG1ADDR(0x0f000d04)
+#define STATUSREG			KSEG1ADDR(0x0f000d04)
+#define REVIDREG			KSEG1ADDR(0x0f000d08)
+#define CLASSREG			KSEG1ADDR(0x0f000d08)
+#define CACHELSREG			KSEG1ADDR(0x0f000d0c)
+#define LATTIMEREG			KSEG1ADDR(0x0f000d0c)
+#define MAILBAREG			KSEG1ADDR(0x0f000d10)
+#define PCIMBA1REG			KSEG1ADDR(0x0f000d14)
+#define PCIMBA2REG			KSEG1ADDR(0x0f000d18)
+#define INTLINEREG			KSEG1ADDR(0x0f000d3c)
+#define INTPINREG			KSEG1ADDR(0x0f000d3c)
+#define RETVALREG			KSEG1ADDR(0x0f000d40)
+#define PCIAPCNTREG			KSEG1ADDR(0x0f000d40)
+
+#define MPCIINTREG			KSEG1ADDR(0x0f0000b2)
+
+#define MAX_PCI_CLOCK			33333333
+
+#define PCIU_CLOCK			0x0080
+#define PCI_CLOCK			0x2000
+
+static inline int pciu_read_config_byte(int where, u8 *val)
+{
+	u32 data;
+
+	data = readl(PCIU_CONFIGREGS_BASE + where);
+	*val = (u8)(data >> ((where & 3) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int pciu_read_config_word(int where, u16 *val)
+{
+	u32 data;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = readl(PCIU_CONFIGREGS_BASE + where);
+	*val = (u16)(data >> ((where & 2) << 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int pciu_read_config_dword(int where, u32 *val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	*val = readl(PCIU_CONFIGREGS_BASE + where);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int pciu_write_config_byte(int where, u8 val)
+{
+	writel(val, PCIU_CONFIGREGS_BASE + where);
+
+	return 0;
+}
+
+static inline int pciu_write_config_word(int where, u16 val)
+{
+	writel(val, PCIU_CONFIGREGS_BASE + where);
+
+	return 0;
+}
+
+static inline int pciu_write_config_dword(int where, u32 val)
+{
+	writel(val, PCIU_CONFIGREGS_BASE + where);
+
+	return 0;
+}
+
+#endif /* __VR41XX_PCIU_H */
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/reset.c linux-2.4.20-pre7/arch/mips/vr41xx/common/reset.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/reset.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/reset.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,37 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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 vr41xx_restart(char *command)
+{
+	change_cp0_status((ST0_BEV | ST0_ERL), (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 vr41xx_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1);
+}
+
+void vr41xx_power_off(void)
+{
+	vr41xx_halt();
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/serial.c linux-2.4.20-pre7/arch/mips/vr41xx/common/serial.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/serial.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/serial.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,178 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/serial.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Serial Interface Unit routines for NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4111 and VR4121.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+/* VR4111 and VR4121 SIU Registers */
+#define VR4111_SIURB		KSEG1ADDR(0x0c000000)
+#define VR4111_SIUIRSEL		KSEG1ADDR(0x0c000008)
+
+/* VR4122 and VR4131 SIU Registers */
+#define VR4122_SIURB		KSEG1ADDR(0x0f000800)
+#define VR4122_SIUIRSEL		KSEG1ADDR(0x0f000808)
+
+ #define USE_RS232C		0x00
+ #define USE_IRDA		0x01
+ #define SIU_USES_IRDA		0x00
+ #define FIR_USES_IRDA		0x02
+ #define IRDA_MODULE_SHARP	0x00
+ #define IRDA_MODULE_TEMIC	0x04
+ #define IRDA_MODULE_HP		0x08
+ #define TMICTX			0x10
+ #define TMICMODE		0x20
+
+#define SIU_BASE_BAUD		1152000
+#define SIU_CLOCK		0x0102
+#define SIU_IRQ			17
+
+/* VR4122 and VR4131 DSIU Registers */
+#define DSIURB			KSEG1ADDR(0x0f000820)
+
+#define MDSIUINTREG		KSEG1ADDR(0x0f000096)
+ #define INTDSIU		0x0800
+
+#define DSIU_BASE_BAUD		1152000
+#define DSIU_CLOCK		0x0802
+#define DSIU_IRQ		29
+
+int vr41xx_serial_ports = 0;
+
+void vr41xx_siu_ifselect(int interface, int module)
+{
+	u16 val = USE_RS232C;	/* Select RS-232C */
+
+	/* Select IrDA */
+	if (interface == SIU_IRDA) {
+		switch (module) {
+		case IRDA_SHARP:
+			val = IRDA_MODULE_SHARP;
+			break;
+		case IRDA_TEMIC:
+			val = IRDA_MODULE_TEMIC;
+			break;
+		case IRDA_HP:
+			val = IRDA_MODULE_HP;
+			break;
+		}
+		val |= USE_IRDA | SIU_USES_IRDA;
+	}
+
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		writew(val, VR4111_SIUIRSEL);
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		writew(val, VR4122_SIUIRSEL);
+		break;
+	default:
+		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+		break;
+	}
+}
+
+void __init vr41xx_siu_init(int interface, int module)
+{
+	struct serial_struct s;
+
+	vr41xx_siu_ifselect(interface, module);
+
+	memset(&s, 0, sizeof(s));
+
+	s.line = vr41xx_serial_ports;
+	s.baud_base = SIU_BASE_BAUD;
+	s.irq = SIU_IRQ;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		s.iomem_base = (unsigned char *)VR4111_SIURB;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		s.iomem_base = (unsigned char *)VR4122_SIURB;
+		break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+	s.iomem_reg_shift = 0;
+	s.io_type = SERIAL_IO_MEM;
+	if (early_serial_setup(&s) != 0)
+		printk(KERN_ERR "SIU setup failed!\n");
+
+	vr41xx_clock_supply(SIU_CLOCK);
+
+	vr41xx_serial_ports++;
+}
+
+void __init vr41xx_dsiu_init(void)
+{
+	struct serial_struct s;
+
+	if (mips_cpu.cputype != CPU_VR4122 && mips_cpu.cputype != CPU_VR4131)
+		return;
+
+	memset(&s, 0, sizeof(s));
+
+	s.line = vr41xx_serial_ports;
+	s.baud_base = DSIU_BASE_BAUD;
+	s.irq = DSIU_IRQ;
+	s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	s.iomem_base = (unsigned char *)DSIURB;
+	s.iomem_reg_shift = 0;
+	s.io_type = SERIAL_IO_MEM;
+	if (early_serial_setup(&s) != 0)
+		printk(KERN_ERR "DSIU setup failed!\n");
+
+	vr41xx_clock_supply(DSIU_CLOCK);
+
+	writew(INTDSIU, MDSIUINTREG);
+
+	vr41xx_serial_ports++;
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/common/time.c linux-2.4.20-pre7/arch/mips/vr41xx/common/time.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/common/time.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/common/time.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,94 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/common/time.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Timer routines for the NEC VR4100 series.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC VR4100 series RTC Unit.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC VR4100 series are supported.
+ */
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/param.h>
+#include <asm/time.h>
+
+#define MIPS_COUNTER_TIMER_IRQ	7
+
+#define VR4111_ETIMELREG	KSEG1ADDR(0x0b0000c0)
+#define VR4122_ETIMELREG	KSEG1ADDR(0x0f000100)
+
+u32 vr41xx_rtc_base = 0;
+
+#ifdef CONFIG_VR41XX_RTC
+extern unsigned long vr41xx_rtc_get_time(void);
+extern int vr41xx_rtc_set_time(unsigned long sec);
+#endif
+
+void vr41xx_time_init(void)
+{
+	switch (mips_cpu.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		vr41xx_rtc_base = VR4111_ETIMELREG;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+                vr41xx_rtc_base = VR4122_ETIMELREG;
+                break;
+        default:
+                panic("Unexpected CPU of NEC VR4100 series");
+                break;
+        }
+
+#ifdef CONFIG_VR41XX_RTC
+        rtc_get_time = vr41xx_rtc_get_time;
+        rtc_set_time = vr41xx_rtc_set_time;
+#endif
+}
+
+void vr41xx_timer_setup(struct irqaction *irq)
+{
+	u32 count;
+
+	setup_irq(MIPS_COUNTER_TIMER_IRQ, irq);
+
+	count = read_32bit_cp0_register(CP0_COUNT);
+	write_32bit_cp0_register (CP0_COMPARE, count + (mips_counter_frequency / HZ));
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/Makefile linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/Makefile
--- linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,25 @@
+#
+# Makefile for the NEC Eagle/Hawk specific parts of the kernel
+#
+# Author: Yoichi Yuasa
+#         yyuasa@mvista.com or source@mvista.com
+#
+# Copyright 2001,2002 MontaVista Software Inc.
+#
+# 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 := eagle.o
+
+all: eagle.o
+
+obj-y	:= init.o irq.o setup.o
+
+obj-$(CONFIG_IDE)	+= ide-eagle.o
+obj-$(CONFIG_PCI)	+= pci_fixup.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/ide-eagle.c linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/ide-eagle.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/ide-eagle.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/ide-eagle.c	Thu Sep 12 20:01:40 2002
@@ -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.
+ *
+ * IDE routines for typical pc-like standard configurations
+ * for the NEC Eagle/Hawk board.
+ *
+ * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  Fri,  5 Apr 2002
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  Fri,  1 Mar 2002
+ *  - Added support for NEC Eagle.
+ */
+#include <linux/sched.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <asm/ptrace.h>
+#include <asm/hdreg.h>
+
+static int eagle_ide_default_irq(ide_ioreg_t base)
+{
+	return 0;
+}
+
+static ide_ioreg_t eagle_ide_default_io_base(int index)
+{
+	return 0;
+}
+
+static void eagle_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 eagle_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, SA_SHIRQ, device, dev_id);
+}
+
+static void eagle_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static int eagle_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return check_region(from, extent);
+}
+
+static void eagle_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                     const char *name)
+{
+	request_region(from, extent, name);
+}
+
+static void eagle_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	release_region(from, extent);
+}
+
+struct ide_ops eagle_ide_ops = {
+	&eagle_ide_default_irq,
+	&eagle_ide_default_io_base,
+	&eagle_ide_init_hwif_ports,
+	&eagle_ide_request_irq,
+	&eagle_ide_free_irq,
+	&eagle_ide_check_region,
+	&eagle_ide_request_region,
+	&eagle_ide_release_region
+};
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/init.c linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/init.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/init.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/init.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,78 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/init.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Initialisation code for the NEC Eagle/Hawk board.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "NEC Eagle/Hawk";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec)
+{
+	int i;
+
+	/*
+	 * collect args and prepare cmd_line
+	 */
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_NEC_EAGLE;
+}
+
+void __init prom_free_prom_memory (void)
+{
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/irq.c linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/irq.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/irq.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/irq.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,186 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/irq.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Interrupt routines for the NEC Eagle/Hawk board.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/vr41xx/eagle.h>
+
+static void enable_pciint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_PCIINTMSKREG);
+	val |= (u8)1 << (irq - PCIINT_IRQ_BASE);
+	writeb(val, NEC_EAGLE_PCIINTMSKREG);
+}
+
+static void disable_pciint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_PCIINTMSKREG);
+	val &= ~((u8)1 << (irq - PCIINT_IRQ_BASE));
+	writeb(val, NEC_EAGLE_PCIINTMSKREG);
+}
+
+static unsigned int startup_pciint_irq(unsigned int irq)
+{
+	enable_pciint_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_pciint_irq	disable_pciint_irq
+#define ack_pciint_irq		disable_pciint_irq
+
+static void end_pciint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_pciint_irq(irq);
+}
+
+static struct hw_interrupt_type pciint_irq_type = {
+	"PCIINT",
+	startup_pciint_irq,
+	shutdown_pciint_irq,
+       	enable_pciint_irq,
+	disable_pciint_irq,
+	ack_pciint_irq,
+	end_pciint_irq,
+	NULL
+};
+
+static void enable_sdbint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_SDBINTMSK);
+	val |= (u8)1 << (irq - SDBINT_IRQ_BASE);
+	writeb(val, NEC_EAGLE_SDBINTMSK);
+}
+
+static void disable_sdbint_irq(unsigned int irq)
+{
+	u8 val;
+
+	val = readb(NEC_EAGLE_SDBINTMSK);
+	val &= ~((u8)1 << (irq - SDBINT_IRQ_BASE));
+	writeb(val, NEC_EAGLE_SDBINTMSK);
+}
+
+static unsigned int startup_sdbint_irq(unsigned int irq)
+{
+	enable_sdbint_irq(irq);
+	return 0; /* never anything pending */
+}
+
+#define shutdown_sdbint_irq	disable_sdbint_irq
+#define ack_sdbint_irq		disable_sdbint_irq
+
+static void end_sdbint_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		enable_sdbint_irq(irq);
+}
+
+static struct hw_interrupt_type sdbint_irq_type = {
+	"SDBINT",
+	startup_sdbint_irq,
+	shutdown_sdbint_irq,
+       	enable_sdbint_irq,
+	disable_sdbint_irq,
+	ack_sdbint_irq,
+	end_sdbint_irq,
+	NULL
+};
+
+static int eagle_get_irq_number(int irq)
+{
+	u8 sdbint, pciint;
+	int i;
+
+	sdbint = readb(NEC_EAGLE_SDBINT);
+	sdbint &= (NEC_EAGLE_SDBINT_DEG | NEC_EAGLE_SDBINT_ENUM |
+	           NEC_EAGLE_SDBINT_SIO1INT | NEC_EAGLE_SDBINT_SIO2INT |
+	           NEC_EAGLE_SDBINT_PARINT);
+	pciint = readb(NEC_EAGLE_PCIINTREG);
+	pciint &= (NEC_EAGLE_PCIINT_CP_INTA | NEC_EAGLE_PCIINT_CP_INTB |
+	           NEC_EAGLE_PCIINT_CP_INTC | NEC_EAGLE_PCIINT_CP_INTD |
+	           NEC_EAGLE_PCIINT_LANINT);
+
+	for (i = 1; i < 6; i++)
+		if (sdbint & (0x01 << i))
+			return SDBINT_IRQ_BASE + i;
+
+	for (i = 0; i < 5; i++)
+		if (pciint & (0x01 << i))
+			return PCIINT_IRQ_BASE + i;
+
+	return -EINVAL;
+}
+
+void __init eagle_irq_init(void)
+{
+	int i;
+
+	writeb(0, NEC_EAGLE_SDBINTMSK);
+	writeb(0, NEC_EAGLE_PCIINTMSKREG);
+
+	vr41xx_set_irq_trigger(VRC4173_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(VRC4173_PIN, LEVEL_LOW);
+
+	vr41xx_set_irq_trigger(PCISLOT_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(PCISLOT_PIN, LEVEL_HIGH);
+
+	vr41xx_set_irq_trigger(FPGA_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(FPGA_PIN, LEVEL_HIGH);
+
+	vr41xx_set_irq_trigger(DCD_PIN, TRIGGER_EDGE, SIGNAL_HOLD);
+	vr41xx_set_irq_level(DCD_PIN, LEVEL_LOW);
+
+	for (i = SDBINT_IRQ_BASE; i <= SDBINT_IRQ_LAST; i++)
+		irq_desc[i].handler = &sdbint_irq_type;
+
+	for (i = PCIINT_IRQ_BASE; i <= PCIINT_IRQ_LAST; i++)
+		irq_desc[i].handler = &pciint_irq_type;
+
+	vr41xx_cascade_irq(FPGA_CASCADE_IRQ, eagle_get_irq_number);
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/pci_fixup.c linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/pci_fixup.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/pci_fixup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/pci_fixup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,166 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/pci_fixup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	The NEC Eagle/Hawk Board specific PCI fixups.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Moved mips_pci_channels[] to arch/mips/vr41xx/vr4122/eagle/setup.c.
+ *  - Added support for NEC Hawk.
+ *
+ *  Paul Mundt <lethal@chaoticdreams.org>
+ *  - Fix empty break statements, remove useless CONFIG_PCI.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/eagle.h>
+#ifdef CONFIG_VRC4173
+#include <asm/vr41xx/vrc4173.h>
+#endif
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	u8 slot, func, pin;
+
+	pci_for_each_dev(dev) {
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		dev->irq = 0;
+
+		switch (slot) {
+		case 8:
+			switch (pin) {
+			case 1:
+				dev->irq = CP_INTA_IRQ;
+				break;
+			case 2:
+				dev->irq = CP_INTB_IRQ;
+				break;
+			case 3:
+				dev->irq = CP_INTC_IRQ;
+				break;
+			case 4:
+				dev->irq = CP_INTD_IRQ;
+				break;
+			}
+			break;
+		case 9:
+			switch (pin) {
+			case 1:
+				dev->irq = CP_INTD_IRQ;
+				break;
+			case 2:
+				dev->irq = CP_INTA_IRQ;
+				break;
+			case 3:
+				dev->irq = CP_INTB_IRQ;
+				break;
+			case 4:
+				dev->irq = CP_INTC_IRQ;
+				break;
+			}
+			break;
+		case 10:
+			switch (pin) {
+			case 1:
+				dev->irq = CP_INTC_IRQ;
+				break;
+			case 2:
+				dev->irq = CP_INTD_IRQ;
+				break;
+			case 3:
+				dev->irq = CP_INTA_IRQ;
+				break;
+			case 4:
+				dev->irq = CP_INTB_IRQ;
+				break;
+			}
+			break;
+#ifdef CONFIG_VRC4173
+		case 12:
+			dev->irq = VRC4173_CARDU1_IRQ;
+			break;
+		case 13:
+			dev->irq = VRC4173_CARDU2_IRQ;
+			break;
+		case 24:
+			dev->irq = VRC4173_CARDU1_IRQ;
+			break;
+		case 25:
+			dev->irq = VRC4173_CARDU2_IRQ;
+			break;
+#endif
+		case 28:
+			dev->irq = LANINTA_IRQ;
+			break;
+		case 29:
+			dev->irq = PCISLOT_IRQ;
+			break;
+#ifdef CONFIG_VRC4173
+		case 30:
+			switch (func) {
+			case 0:
+				dev->irq = VRC4173_IRQ;
+				break;
+			case 1:
+				dev->irq = VRC4173_AC97U_IRQ;
+				break;
+			case 2:
+				dev->irq = VRC4173_USBU_IRQ;
+				break;
+			}
+			break;
+#endif
+		}
+
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/setup.c linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/setup.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/nec-eagle/setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/nec-eagle/setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,156 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/nec-eagle/setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Setup for the NEC Eagle/Hawk board.
+ *
+ * Author: Yoichi Yuasa
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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.
+ */
+/*
+ * Changes:
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - Moved mips_pci_channels[] from arch/mips/vr41xx/vr4122/eagle/setup.c.
+ *  - Added support for NEC Hawk.
+ *
+ *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
+ *  - New creation, NEC Eagle is supported.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+
+#include <asm/pci_channel.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/vr41xx/eagle.h>
+
+#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 eagle_ide_ops;
+#endif
+
+extern void eagle_irq_init(void);
+
+#ifdef CONFIG_PCI
+static struct resource vr41xx_pci_io_resource = {
+	"PCI I/O space",
+	VR41XX_PCI_IO_START,
+	VR41XX_PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource vr41xx_pci_mem_resource = {
+	"PCI memory space",
+	VR41XX_PCI_MEM_START,
+	VR41XX_PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops vr41xx_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
+	{NULL, NULL, NULL, 0, 0}
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem1 = {
+	VR41XX_PCI_MEM1_BASE,
+	VR41XX_PCI_MEM1_MASK,
+	IO_MEM1_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem2 = {
+	VR41XX_PCI_MEM2_BASE,
+	VR41XX_PCI_MEM2_MASK,
+	IO_MEM2_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_io = {
+	VR41XX_PCI_IO_BASE,
+	VR41XX_PCI_IO_MASK,
+	IO_PORT_RESOURCE_START
+};
+
+static struct vr41xx_pci_address_map pci_address_map = {
+	&vr41xx_pci_mem1,
+	&vr41xx_pci_mem2,
+	&vr41xx_pci_io
+};
+#endif
+
+void __init nec_eagle_setup(void)
+{
+	set_io_port_base(IO_PORT_BASE);
+	ioport_resource.start = IO_PORT_RESOURCE_START;
+	ioport_resource.end = IO_PORT_RESOURCE_END;
+	iomem_resource.start = IO_MEM1_RESOURCE_START;
+	iomem_resource.end = IO_MEM2_RESOURCE_END;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+	_machine_restart = vr41xx_restart;
+	_machine_halt = vr41xx_halt;
+	_machine_power_off = vr41xx_power_off;
+
+	board_time_init = vr41xx_time_init;
+	board_timer_setup = vr41xx_timer_setup;
+
+	board_irq_init = eagle_irq_init;
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &eagle_ide_ops;
+#endif
+
+	vr41xx_bcu_init();
+
+	vr41xx_cmu_init(0);
+
+	vr41xx_dsiu_init();
+	vr41xx_siu_init(SIU_RS232C, 0);
+
+#ifdef CONFIG_PCI
+	vr41xx_pciu_init(&pci_address_map);
+#endif
+
+#ifdef CONFIG_VRC4173
+	vrc4173_init();
+#endif
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/Makefile linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/Makefile
--- linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/Makefile	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,20 @@
+#
+# Makefile for the ZAO Networks Capcella  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 := capcella.o
+
+all: capcella.o
+
+obj-y	:= init.o setup.o
+
+obj-$(CONFIG_IDE)	+= ide-capcella.o
+obj-$(CONFIG_PCI)	+= pci_fixup.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/ide-capcella.c linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/ide-capcella.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/ide-capcella.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/ide-capcella.c	Thu Sep 12 20:01:40 2002
@@ -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.
+ *
+ * IDE routines for typical pc-like standard configurations
+ * for the ZAO Networks Capcella.
+ *
+ * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
+ */
+/*
+ * Changes:
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Sun, 24 Feb 2002
+ *  - Added ZAO Networks Capcella support.
+ */
+#include <linux/sched.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+#include <linux/hdreg.h>
+#include <asm/ptrace.h>
+#include <asm/hdreg.h>
+
+static int capcella_ide_default_irq(ide_ioreg_t base)
+{
+	switch (base) {
+	case 0x8300: return 42;
+	}
+
+	return 0;
+}
+
+static ide_ioreg_t capcella_ide_default_io_base(int index)
+{
+	switch (index) {
+	case 0: return 0x8300;
+	}
+
+	return 0;
+}
+
+static void capcella_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 capcella_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 capcella_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static int capcella_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	return check_region(from, extent);
+}
+
+static void capcella_ide_request_region(ide_ioreg_t from, unsigned int extent,
+                                        const char *name)
+{
+	request_region(from, extent, name);
+}
+
+static void capcella_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+	release_region(from, extent);
+}
+
+struct ide_ops capcella_ide_ops = {
+	&capcella_ide_default_irq,
+	&capcella_ide_default_io_base,
+	&capcella_ide_init_hwif_ports,
+	&capcella_ide_request_irq,
+	&capcella_ide_free_irq,
+	&capcella_ide_check_region,
+	&capcella_ide_request_region,
+	&capcella_ide_release_region
+};
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/init.c linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/init.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/init.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/init.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,68 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/zao-capcella/init.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Initialisation code for the ZAO Networks Capcella.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the 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>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/vr41xx/vr41xx.h>
+
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+	return "ZAO Networks Capcella";
+}
+
+void __init bus_error_init(void)
+{
+}
+
+void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec)
+{
+	u32 config;
+	int i;
+
+	/*
+	 * collect args and prepare cmd_line
+	 */
+	for (i = 1; i < argc; i++) {
+		strcat(arcs_cmdline, argv[i]);
+		if (i < (argc - 1))
+			strcat(arcs_cmdline, " ");
+	}
+
+	mips_machgroup = MACH_GROUP_NEC_VR41XX;
+	mips_machtype = MACH_ZAO_CAPCELLA;
+
+	switch (mips_cpu.processor_id) {
+	case PRID_VR4131_REV1_2:
+		config = read_32bit_cp0_register(CP0_CONFIG);
+		config &= ~0x00000030UL;
+		config |= 0x00410000UL;
+		write_32bit_cp0_register(CP0_CONFIG, config);
+		break;
+	default:
+		break;
+	}
+}
+
+void __init prom_free_prom_memory (void)
+{
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/pci_fixup.c linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/pci_fixup.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/pci_fixup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/pci_fixup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,73 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/zao-capcella/pci_fixup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	The ZAO Networks Capcella specific PCI fixups.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the 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/pci.h>
+
+#include <asm/vr41xx/capcella.h>
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+}
+
+void __init pcibios_fixup(void)
+{
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+	struct pci_dev *dev;
+	u8 slot, func, pin;
+
+	pci_for_each_dev(dev) {
+		slot = PCI_SLOT(dev->devfn);
+		func = PCI_FUNC(dev->devfn);
+		dev->irq = 0;
+
+		switch (slot) {
+		case 11:
+			dev->irq = RTL8139_1_IRQ;
+			break;
+		case 12:
+			dev->irq = RTL8139_2_IRQ;
+			break;
+		case 14:
+			pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+			switch (pin) {
+			case 1:
+				dev->irq = PC104PLUS_INTA_IRQ;
+				break;
+			case 2:
+				dev->irq = PC104PLUS_INTB_IRQ;
+				break;
+			case 3:
+				dev->irq = PC104PLUS_INTC_IRQ;
+				break;
+			case 4:
+				dev->irq = PC104PLUS_INTD_IRQ;
+				break;
+			}
+			break;
+		}
+
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	}
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 0;
+}
diff -urN linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/setup.c linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/setup.c
--- linux-2.4.20-pre6/arch/mips/vr41xx/zao-capcella/setup.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips/vr41xx/zao-capcella/setup.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,121 @@
+/*
+ * FILE NAME
+ *	arch/mips/vr41xx/zao-capcella/setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Setup for the ZAO Networks Capcella.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the 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/console.h>
+#include <linux/ide.h>
+#include <linux/ioport.h>
+
+#include <asm/pci_channel.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/vr41xx/capcella.h>
+
+#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 capcella_ide_ops;
+#endif
+
+#ifdef CONFIG_PCI
+static struct resource vr41xx_pci_io_resource = {
+	"PCI I/O space",
+	VR41XX_PCI_IO_START,
+	VR41XX_PCI_IO_END,
+	IORESOURCE_IO
+};
+
+static struct resource vr41xx_pci_mem_resource = {
+	"PCI memory space",
+	VR41XX_PCI_MEM_START,
+	VR41XX_PCI_MEM_END,
+	IORESOURCE_MEM
+};
+
+extern struct pci_ops vr41xx_pci_ops;
+
+struct pci_channel mips_pci_channels[] = {
+	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
+	{NULL, NULL, NULL, 0, 0}
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem1 = {
+	VR41XX_PCI_MEM1_BASE,
+	VR41XX_PCI_MEM1_MASK,
+	IO_MEM1_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_mem2 = {
+	VR41XX_PCI_MEM2_BASE,
+	VR41XX_PCI_MEM2_MASK,
+	IO_MEM2_RESOURCE_START
+};
+
+struct vr41xx_pci_address_space vr41xx_pci_io = {
+	VR41XX_PCI_IO_BASE,
+	VR41XX_PCI_IO_MASK,
+	IO_PORT_RESOURCE_START
+};
+
+static struct vr41xx_pci_address_map pci_address_map = {
+	&vr41xx_pci_mem1,
+	&vr41xx_pci_mem2,
+	&vr41xx_pci_io
+};
+#endif
+
+void __init zao_capcella_setup(void)
+{
+	set_io_port_base(IO_PORT_BASE);
+	ioport_resource.start = IO_PORT_RESOURCE_START;
+	ioport_resource.end = IO_PORT_RESOURCE_END;
+	iomem_resource.start = IO_MEM1_RESOURCE_START;
+	iomem_resource.end = IO_MEM2_RESOURCE_END;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
+#endif
+
+	_machine_restart = vr41xx_restart;
+	_machine_halt = vr41xx_halt;
+	_machine_power_off = vr41xx_power_off;
+
+	board_time_init = vr41xx_time_init;
+	board_timer_setup = vr41xx_timer_setup;
+
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_ops = &capcella_ide_ops;
+#endif
+
+	vr41xx_bcu_init();
+
+	vr41xx_cmu_init(0x0102);
+
+	vr41xx_siu_init(SIU_RS232C, 0);
+
+#ifdef CONFIG_PCI
+	vr41xx_pciu_init(&pci_address_map);
+#endif
+}
diff -urN linux-2.4.20-pre6/arch/mips64/Makefile linux-2.4.20-pre7/arch/mips64/Makefile
--- linux-2.4.20-pre6/arch/mips64/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/Makefile	Thu Sep 12 20:01:40 2002
@@ -25,7 +25,7 @@
 endif
 
 #
-# The ELF GCC uses -G0 -mabicalls -fpic as default.  We don't need PIC
+# The ELF GCC uses -G 0 -mabicalls -fpic as default.  We don't need PIC
 # code in the kernel since it only slows down the whole thing.  For the
 # old GCC these options are just the defaults.  At some point we might
 # make use of global pointer optimizations.
@@ -67,10 +67,10 @@
 ifdef CONFIG_CPU_SB1
 GCCFLAGS	+= -mcpu=r8000 -mips4
 endif
-
-AFLAGS		+= $(GCCFLAGS)
-CFLAGS		+= $(GCCFLAGS)
-
+ifdef CONFIG_CPU_MIPS64
+#CFLAGS		+= -mips64	# Should be used then we get a MIPS64 compiler
+CFLAGS		+= -mcpu=r8000 -mips4
+endif
 
 #
 # We unconditionally build the math emulator
@@ -104,12 +104,22 @@
 endif
 
 #
+# MIPS SEAD board
+#
+ifdef CONFIG_MIPS_SEAD
+LIBS		+= arch/mips/mips-boards/sead/sead.o \
+		   arch/mips/mips-boards/generic/mipsboards.o
+SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/sead
+LOADADDR	:= 0x80100000
+endif
+
+#
 # SGI IP22 (Indy/Indigo2)
 #
 ifdef CONFIG_SGI_IP22
 CORE_FILES	+= arch/mips/sgi-ip22/ip22-kern.o
-LIBS		+= arch/mips64/arc/arclib.a 
-SUBDIRS		+= arch/mips/sgi-ip22 arch/mips64/arc
+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,
 # 0x88004000 for production kernels.  Note that the value must be
@@ -122,9 +132,9 @@
 # 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/mips/sgi-ip27/ip27.o
+LIBS		+= arch/mips/arc/arclib.a
+SUBDIRS		+= arch/mips/sgi-ip27 arch/mips/arc
 #
 # Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
 # symmon, 0xc00000000001c000 for production kernels.  Note that the value
@@ -142,9 +152,9 @@
 # SGI-IP32 (O2)
 #
 ifdef CONFIG_SGI_IP32
-CORE_FILES	+= arch/mips64/sgi-ip32/ip32-kern.a
-LIBS		+= arch/mips64/arc/arclib.a
-SUBDIRS		+= arch/mips64/sgi-ip32 arch/mips64/arc
+CORE_FILES	+= arch/mips/sgi-ip32/ip32-kern.a
+LIBS		+= arch/mips/arc/arclib.a
+SUBDIRS		+= arch/mips/sgi-ip32 arch/mips/arc
 #
 # Set LOADADDR to >= 0x????????? if you want to leave space for symmon,
 # 0x80002000 for production kernels.  Note that the value must be
@@ -174,6 +184,14 @@
 endif
 
 #
+# Sibyte CFE firmware
+#
+ifdef CONFIG_SIBYTE_CFE
+LIBS		+= arch/mips/sibyte/cfe/cfe.a
+SUBDIRS		+= arch/mips/sibyte/cfe
+endif
+
+#
 # SB1 Cache Error handler
 #
 ifdef CONFIG_SB1_CACHE_ERROR
@@ -188,8 +206,7 @@
 # convert to ECOFF using elf2ecoff.
 #
 ifdef CONFIG_BOOT_ELF32
-CFLAGS += -Wa,-32
-AFLAGS += -Wa,-32
+GCCFLAGS += -Wa,-32
 LINKFLAGS += -T arch/mips64/ld.script.elf32
 endif
 #
@@ -197,19 +214,23 @@
 # ELF files from 32-bit files by conversion.
 #
 ifdef CONFIG_BOOT_ELF64
-CFLAGS += -Wa,-32
-AFLAGS += -Wa,-32
+GCCFLAGS += -Wa,-32
 LINKFLAGS += -T arch/mips64/ld.script.elf32
 #AS += -64
 #LD += -m elf64bmip
 #LINKFLAGS += -T arch/mips64/ld.script.elf64
 endif
 
+
+AFLAGS		+= $(GCCFLAGS)
+CFLAGS		+= $(GCCFLAGS)
+
+
 LINKFLAGS += -Ttext $(LOADADDR)
 
 HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
 
-SUBDIRS := $(addprefix arch/mips64/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib)
+SUBDIRS := $(addprefix arch/mips/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib)
 CORE_FILES := arch/mips64/kernel/kernel.o arch/mips64/mm/mm.o $(CORE_FILES)
 LIBS := arch/mips64/lib/lib.a $(LIBS)
 
@@ -243,12 +264,12 @@
 
 archclean:
 	@$(MAKEBOOT) clean
-	$(MAKE) -C arch/$(ARCH)/tools clean
+	$(MAKE) -C arch/mips/tools clean
 	rm -f vmlinux.64 arch/$(ARCH)/ld.script.elf32
 
 archmrproper:
 	@$(MAKEBOOT) mrproper
-	$(MAKE) -C arch/$(ARCH)/tools mrproper
+	$(MAKE) -C arch/mips/tools mrproper
 
 archdep:
 	if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
diff -urN linux-2.4.20-pre6/arch/mips64/arc/Makefile linux-2.4.20-pre7/arch/mips64/arc/Makefile
--- linux-2.4.20-pre6/arch/mips64/arc/Makefile	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,12 +0,0 @@
-#
-# Makefile for the ARC prom monitor library routines under Linux.
-#
-
-L_TARGET = arclib.a
-obj-y	:= console.o init.o identify.o tree.o env.o cmdline.o misc.o time.o \
-	   file.o
-
-obj-$(CONFIG_ARC_MEMORY) += memory.o
-obj-$(CONFIG_ARC_CONSOLE) += arc_con.o
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/arc/arc_con.c linux-2.4.20-pre7/arch/mips64/arc/arc_con.c
--- linux-2.4.20-pre6/arch/mips64/arc/arc_con.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/arc/arc_con.c	Wed Dec 31 16:00:00 1969
@@ -1,62 +0,0 @@
-/*
- * Wrap-around code for a console using the
- * ARC io-routines.
- *
- * Copyright (c) 1998 Harald Koerfgen 
- * Copyright (c) 2001 Ralf Baechle
- */
-#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 <asm/sgialib.h>
-
-extern void prom_printf (char *, ...);
-
-void prom_putchar(char c)
-{
-	ULONG cnt;
-	CHAR it = c;
-
-	ArcWrite(1, &it, 1, &cnt);
-}
-
-static void prom_console_write(struct console *co, const char *s,
-			       unsigned count)
-{
-	unsigned i;
-
-	/*
-	 *    Now, do each character
-	 */
-	for (i = 0; i < count; i++) {
-		if (*s == 10)
-			prom_printf("%c", 13);
-		prom_printf("%c", *s++);
-	}
-}
-
-static kdev_t prom_console_device(struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
-}
-
-static struct console arc_cons = {
-    name:	"ttyS",
-    write:	prom_console_write,
-    device:	prom_console_device,
-    flags:	CON_PRINTBUFFER,
-    index:	-1,
-};
-
-/*
- *    Register console.
- */
-
-void __init arc_console_init(void)
-{
-	register_console(&arc_cons);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/cmdline.c linux-2.4.20-pre7/arch/mips64/arc/cmdline.c
--- linux-2.4.20-pre6/arch/mips64/arc/cmdline.c	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/cmdline.c	Wed Dec 31 16:00:00 1969
@@ -1,111 +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.
- *
- * cmdline.c: Kernel command line creation using ARCS argc/argv.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-/* #define DEBUG_CMDLINE */
-
-char arcs_cmdline[CL_SIZE];
-
-char * __init prom_getcmdline(void)
-{
-	return &(arcs_cmdline[0]);
-}
-
-static char *ignored[] = {
-	"ConsoleIn=",
-	"ConsoleOut=",
-	"SystemPartition=",
-	"OSLoader=",
-	"OSLoadPartition=",
-	"OSLoadFilename=",
-	"OSLoadOptions="
-};
-#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
-
-static char *used_arc[][2] = {
-	{ "OSLoadPartition=", "root=" },
-	{ "OSLoadOptions=", "" }
-};
-
-static char * __init move_firmware_args(char* cp)
-{
-	char *s;
-	int actr, i;
-
-	actr = 1; /* Always ignore argv[0] */
-
-	while (actr < prom_argc) {
-		for(i = 0; i < NENTS(used_arc); i++) {
-			int len = strlen(used_arc[i][0]);
-
-			if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
-			/* Ok, we want it. First append the replacement... */
-				strcat(cp, used_arc[i][1]);
-				cp += strlen(used_arc[i][1]);
-				/* ... and now the argument */
-				s = strstr(prom_argv(actr), "=");
-				if (s) {
-					s++;
-					strcpy(cp, s);
-					cp += strlen(s);
-				}
-				*cp++ = ' ';
-				break;
-			}
-		}
-		actr++;
-	}
-
-	return cp;
-}
-
-
-void __init prom_init_cmdline(void)
-{
-	char *cp;
-	int actr, i;
-
-	actr = 1; /* Always ignore argv[0] */
-
-	cp = &(arcs_cmdline[0]);
-	/* 
-	 * Move ARC variables to the beginning to make sure they can be
-	 * overridden by later arguments.
-	 */
-	cp = move_firmware_args(cp);
-
-	while (actr < prom_argc) {
-		for (i = 0; i < NENTS(ignored); i++) {
-			int len = strlen(ignored[i]);
-
-			if (!strncmp(prom_argv(actr), ignored[i], len))
-				goto pic_cont;
-		}
-		/* Ok, we want it. */
-		strcpy(cp, prom_argv(actr));
-		cp += strlen(prom_argv(actr));
-		*cp++ = ' ';
-
-	pic_cont:
-		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 -urN linux-2.4.20-pre6/arch/mips64/arc/console.c linux-2.4.20-pre7/arch/mips64/arc/console.c
--- linux-2.4.20-pre6/arch/mips64/arc/console.c	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/console.c	Wed Dec 31 16:00:00 1969
@@ -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) 1996 David S. Miller (dm@sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/sgialib.h>
-
-static char ppbuf[1024];
-
-void prom_printf(char *fmt, ...)
-{
-	va_list args;
-	char ch, *bptr;
-	int i;
-
-	va_start(args, fmt);
-	i = vsprintf(ppbuf, fmt, args);
-
-	bptr = ppbuf;
-
-	while((ch = *(bptr++)) != 0) {
-		if(ch == '\n')
-			prom_putchar('\r');
-
-		prom_putchar(ch);
-	}
-	va_end(args);
-	return;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/env.c linux-2.4.20-pre7/arch/mips64/arc/env.c
--- linux-2.4.20-pre6/arch/mips64/arc/env.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/env.c	Wed Dec 31 16:00:00 1969
@@ -1,27 +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.
- *
- * env.c: ARCS environment variable routines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#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 (CHAR *) ARC_CALL1(get_evar, name);
-}
-
-LONG __init
-ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
-{
-	return ARC_CALL2(set_evar, name, value);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/file.c linux-2.4.20-pre7/arch/mips64/arc/file.c
--- linux-2.4.20-pre6/arch/mips64/arc/file.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/file.c	Wed Dec 31 16:00:00 1969
@@ -1,75 +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.
- *
- * ARC firmware interface.
- *
- * 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
-ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
-                     ULONG N, ULONG *Count)
-{
-	return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
-}
-
-LONG __init
-ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
-{
-	return ARC_CALL3(open, Path, OpenMode, FileID);
-}
-
-LONG __init
-ArcClose(ULONG FileID)
-{
-	return ARC_CALL1(close, FileID);
-}
-
-LONG __init
-ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
-{
-	return ARC_CALL4(read, FileID, Buffer, N, Count);
-}
-
-LONG __init
-ArcGetReadStatus(ULONG FileID)
-{
-	return ARC_CALL1(get_rstatus, FileID);
-}
-
-LONG __init
-ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
-{
-	return ARC_CALL4(write, FileID, Buffer, N, Count);
-}
-
-LONG __init
-ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
-{
-	return ARC_CALL3(seek, FileID, Position, SeekMode);
-}
-
-LONG __init
-ArcMount(char *name, enum linux_mountops op)
-{
-	return ARC_CALL2(mount, name, op);
-}
-
-LONG __init
-ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
-{
-	return ARC_CALL2(get_finfo, FileID, Information);
-}
-
-LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
-                                  ULONG AttributeMask)
-{
-	return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/identify.c linux-2.4.20-pre7/arch/mips64/arc/identify.c
--- linux-2.4.20-pre6/arch/mips64/arc/identify.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/arc/identify.c	Wed Dec 31 16:00:00 1969
@@ -1,117 +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.
- *
- * identify.c: identify machine by looking up system identifier
- *
- * Copyright (C) 1998 Thomas Bogendoerfer
- * 
- * This code is based on arch/mips/sgi/kernel/system.c, which is
- * 
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-
-#include <asm/sgialib.h>
-#include <asm/bootinfo.h>
-
-struct smatch {
-	char *arcname;
-	char *liname;
-	int group;
-	int type;
-	int flags;
-};
-
-static struct smatch mach_table[] = {
-	{	"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)
-{
-	int i;
-    
-	for (i = 0; i < (sizeof (mach_table) / sizeof (mach_table[0])); i++) {
-		if(!strcmp(s, mach_table[i].arcname))
-			return &mach_table[i];
-	}
-	panic("Yeee, could not determine architecture type <%s>", s);
-
-	return NULL;
-}
-
-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 = 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;
-	prom_flags = mach->flags;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/init.c linux-2.4.20-pre7/arch/mips64/arc/init.c
--- linux-2.4.20-pre6/arch/mips64/arc/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/arc/init.c	Wed Dec 31 16:00:00 1969
@@ -1,49 +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.
- *
- * PROM library initialisation code.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/sgialib.h>
-
-#undef DEBUG_PROM_INIT
-
-/* Master romvec interface. */
-struct linux_romvec *romvec;
-int prom_argc;
-LONG *_prom_argv, *_prom_envp;
-
-int __init prom_init(int argc, char **argv, char **envp)
-{
-	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
-	romvec = ROMVECTOR;
-	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);
-		while(1)
-			;
-	}
-
-	prom_init_cmdline();
-	prom_identify_arch();
-	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");
-	prom_getchar();
-	ArcEnterInteractiveMode();
-#endif
-	return 0;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/memory.c linux-2.4.20-pre7/arch/mips64/arc/memory.c
--- linux-2.4.20-pre6/arch/mips64/arc/memory.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/arc/memory.c	Wed Dec 31 16:00:00 1969
@@ -1,159 +0,0 @@
-/*
- * memory.c: PROM library functions for acquiring/using memory descriptors
- *           given to us from the ARCS firmware.
- *
- * Copyright (C) 1996 by David S. Miller
- * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
- *
- * PROM library functions for acquiring/using memory descriptors given to us
- * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
- * because on some machines like SGI IP27 the ARC memory configuration data
- * completly bogus and alternate easier to use mechanisms are available.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/swap.h>
-
-#include <asm/sgialib.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/bootinfo.h>
-
-#undef DEBUG
-
-struct linux_mdesc* __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
-{
-	return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
-}
-
-#ifdef DEBUG /* convenient for debugging */
-static char *arcs_mtypes[8] = {
-	"Exception Block",
-	"ARCS Romvec Page",
-	"Free/Contig RAM",
-	"Generic Free RAM",
-	"Bad Memory",
-	"Standalone Program Pages",
-	"ARCS Temp Storage Area",
-	"ARCS Permanent Storage Area"
-};
-
-static char *arc_mtypes[8] = {
-	"Exception Block",
-	"SystemParameterBlock",
-	"FreeMemory",
-	"Bad Memory",
-	"LoadedProgram",
-	"FirmwareTemporary",
-	"FirmwarePermanent",
-	"FreeContiguous"
-};
-#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
-						: arc_mtypes[a.arc]
-#endif
-
-static inline int memtype_classify_arcs (union linux_memtypes type)
-{
-	switch (type.arcs) {
-	case arcs_fcontig:
-	case arcs_free:
-		return BOOT_MEM_RAM;
-	case arcs_atmp:
-		return BOOT_MEM_ROM_DATA;
-	case arcs_eblock:
-	case arcs_rvpage:
-	case arcs_bmem:
-	case arcs_prog:
-	case arcs_aperm:
-		return BOOT_MEM_RESERVED;
-	default:
-		BUG();
-	}
-	while(1);				/* Nuke warning.  */
-}
-
-static inline int memtype_classify_arc (union linux_memtypes type)
-{
-	switch (type.arc) {
-	case arc_free:
-	case arc_fcontig:
-		return BOOT_MEM_RAM;
-	case arc_atmp:
-		return BOOT_MEM_ROM_DATA;
-	case arc_eblock:
-	case arc_rvpage:
-	case arc_bmem:
-	case arc_prog:
-	case arc_aperm:
-		return BOOT_MEM_RESERVED;
-	default:
-		BUG();
-	}
-	while(1);				/* Nuke warning.  */
-}
-
-static int __init prom_memtype_classify (union linux_memtypes type)
-{
-	if (prom_flags & PROM_FLAG_ARCS)	/* SGI is ``different'' ... */
-		return memtype_classify_arcs(type);
-
-	return memtype_classify_arc(type);
-}
-
-void __init prom_meminit(void)
-{
-	struct linux_mdesc *p;
-
-#ifdef DEBUG
-	int i = 0;
-
-	prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
-	p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
-	while(p) {
-		prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
-			    i, p, p->base, p->pages, mtypes(p->type));
-		p = ArcGetMemoryDescriptor(p);
-		i++;
-	}
-#endif
-
-	p = PROM_NULL_MDESC;
-	while ((p = ArcGetMemoryDescriptor(p))) {
-		unsigned long base, size;
-		long type;
-
-		base = p->base << PAGE_SHIFT;
-		size = p->pages << PAGE_SHIFT;
-		type = prom_memtype_classify(p->type);
-
-		add_memory_region(base, size, type);
-	}
-}
-
-void __init prom_free_prom_memory (void)
-{
-	unsigned long freed = 0;
-	unsigned long addr;
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
-		while (addr < boot_mem_map.map[i].addr
-			      + boot_mem_map.map[i].size) {
-			ClearPageReserved(virt_to_page(__va(addr)));
-			set_page_count(virt_to_page(__va(addr)), 1);
-			free_page((unsigned long)__va(addr));
-			addr += PAGE_SIZE;
-			freed += PAGE_SIZE;
-		}
-	}
-	printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/misc.c linux-2.4.20-pre7/arch/mips64/arc/misc.c
--- linux-2.4.20-pre6/arch/mips64/arc/misc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/arc/misc.c	Wed Dec 31 16:00:00 1969
@@ -1,103 +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.
- *
- * 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>
-
-extern void *sgiwd93_host;
-extern void reset_wd33c93(void *instance);
-
-VOID
-ArcHalt(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(halt);
-never:	goto never;
-}
-
-VOID
-ArcPowerDown(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(pdown);
-never:	goto never;
-}
-
-/* XXX is this a soft reset basically? XXX */
-VOID
-ArcRestart(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(restart);
-never:	goto never;
-}
-
-VOID
-ArcReboot(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(reboot);
-never:	goto never;
-}
-
-VOID
-ArcEnterInteractiveMode(VOID)
-{
-	bc_disable();
-	cli();
-#if CONFIG_SCSI_SGIWD93
-	reset_wd33c93(sgiwd93_host);
-#endif
-	ARC_CALL0(imode);
-never:	goto never;
-}
-
-LONG
-ArcSaveConfiguration(VOID)
-{
-	return ARC_CALL0(cfg_save);
-}
-
-struct linux_sysid *
-ArcGetSystemId(VOID)
-{
-	return (struct linux_sysid *) ARC_CALL0(get_sysid);
-}
-
-VOID __init
-ArcFlushAllCaches(VOID)
-{
-	ARC_CALL0(cache_flush);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/salone.c linux-2.4.20-pre7/arch/mips64/arc/salone.c
--- linux-2.4.20-pre6/arch/mips64/arc/salone.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/salone.c	Wed Dec 31 16:00:00 1969
@@ -1,27 +0,0 @@
-/*
- * Routines to load into memory and execute stand-along program images using
- * ARCS PROM firmware.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- */
-#include <linux/init.h>
-#include <asm/sgialib.h>
-
-LONG __init
-ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
-{
-	return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
-}
-
-LONG __init
-ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
-          CHAR *Envp[])
-{
-	return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
-}
-
-LONG __init
-ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
-{
-	return ARC_CALL4(exec, Path, Argc, Argv, Envp);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/time.c linux-2.4.20-pre7/arch/mips64/arc/time.c
--- linux-2.4.20-pre6/arch/mips64/arc/time.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/arc/time.c	Wed Dec 31 16:00:00 1969
@@ -1,25 +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.
- *
- * Extracting time information from ARCS prom.
- *
- * 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
-ArcGetTime(VOID)
-{
-	return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
-}
-
-ULONG __init
-ArcGetRelativeTime(VOID)
-{
-	return ARC_CALL0(get_rtime);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/arc/tree.c linux-2.4.20-pre7/arch/mips64/arc/tree.c
--- linux-2.4.20-pre6/arch/mips64/arc/tree.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/arc/tree.c	Wed Dec 31 16:00:00 1969
@@ -1,129 +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.
- *
- * PROM component device tree code.
- *
- * 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>
-#include <asm/sgiarcs.h>
-
-#undef DEBUG_PROM_TREE
-
-pcomponent * __init
-ArcGetPeer(pcomponent *Current)
-{
-	if (Current == PROM_NULL_COMPONENT)
-		return PROM_NULL_COMPONENT;
-
-	return (pcomponent *) ARC_CALL1(next_component, Current);
-}
-
-pcomponent * __init
-ArcGetChild(pcomponent *Current)
-{
-	return (pcomponent *) ARC_CALL1(child_component, Current);
-}
-
-pcomponent * __init
-ArcGetParent(pcomponent *Current)
-{
-	if (Current == PROM_NULL_COMPONENT)
-		return PROM_NULL_COMPONENT;
-
-	return (pcomponent *) ARC_CALL1(parent_component, Current);
-}
-
-LONG __init
-ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
-{
-	return ARC_CALL2(component_data, Buffer, Current);
-}
-
-pcomponent * __init
-ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
-{
-	return (pcomponent *)
-	       ARC_CALL3(child_add, Current, Template, ConfigurationData);
-}
-
-LONG __init
-ArcDeleteComponent(pcomponent *ComponentToDelete)
-{
-	return ARC_CALL1(comp_del, ComponentToDelete);
-}
-
-pcomponent * __init
-ArcGetComponent(CHAR *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"
-};
-
-static char *iflags[] = {
-	"bogus", "read only", "removable", "console in", "console out",
-	"input", "output"
-};
-
-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],
-		    iflags[p->iflags], p->vers, p->rev);
-	prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
-		    p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
-}
-
-static void __init
-traverse(pcomponent *p, int op)
-{
-	dump_component(p);
-	if(ArcGetChild(p))
-		traverse(ArcGetChild(p), 1);
-	if(ArcGetPeer(p) && op)
-		traverse(ArcGetPeer(p), 1);
-}
-
-void __init
-prom_testtree(void)
-{
-	pcomponent *p;
-
-	p = ArcGetChild(PROM_NULL_COMPONENT);
-	dump_component(p);
-	p = ArcGetChild(p);
-	while(p) {
-		dump_component(p);
-		p = ArcGetPeer(p);
-	}
-}
-
-#endif /* DEBUG_PROM_TREE  */
diff -urN linux-2.4.20-pre6/arch/mips64/config.in linux-2.4.20-pre7/arch/mips64/config.in
--- linux-2.4.20-pre6/arch/mips64/config.in	Thu Sep 12 20:01:31 2002
+++ linux-2.4.20-pre7/arch/mips64/config.in	Thu Sep 12 20:01:40 2002
@@ -3,338 +3,7 @@
 # see Documentation/kbuild/config-language.txt.
 #
 define_bool CONFIG_MIPS y
+define_bool CONFIG_MIPS32 n
 define_bool CONFIG_MIPS64 y
 
-mainmenu_name "Linux/MIPS64 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 '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
-   bool '  NUMA support' CONFIG_NUMA
-   bool '  Mapped kernel support' CONFIG_MAPPED_KERNEL
-   bool '  Kernel text replication support' CONFIG_REPLICATE_KTEXT
-   bool '  Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS
-   bool '  Multi-Processing support' CONFIG_SMP
-   #bool '  IP27 XXL' CONFIG_SGI_SN0_XXL
-fi
-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.
-#
-
-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_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_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_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_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
-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 \
-	 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'
-
-if [ "$CONFIG_CPU_R10000" = "y" ]; then
-   bool 'Support for large 64-bit configurations' CONFIG_MIPS_INSANE_LARGE
-fi
-bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
-
-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
-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
-define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT
-tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-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
-
-if [ "$CONFIG_NET" = "y" ]; then
-   source net/Config.in
-fi
-
-source drivers/telephony/Config.in
-
-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
-      define_bool CONFIG_BLK_DEV_IDE_MODES n
-      define_bool CONFIG_BLK_DEV_HD n
-   fi
-   endmenu
-fi
-
-mainmenu_option next_comment
-comment 'SCSI support'
-
-tristate 'SCSI support' CONFIG_SCSI
-
-if [ "$CONFIG_SCSI" != "n" ]; then
-   source drivers/scsi/Config.in
-fi
-endmenu
-
-if [ "$CONFIG_PCI" = "y" ]; then
-   source drivers/message/i2o/Config.in
-fi
-
-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
-
-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
-
-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
-   fi
-   endmenu
-fi
-
-source drivers/char/Config.in
-
-#source drivers/misc/Config.in
-
-source drivers/media/Config.in
-
-if [ "$CONFIG_SGI_IP22" = "y" ]; then
-   mainmenu_option next_comment
-   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_FONT_8x16 y
-      fi
-      define_bool CONFIG_DUMMY_CONSOLE y
-   fi
-   endmenu
-fi
-
-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
-comment 'Sound'
-
-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
-comment 'Kernel hacking'
-
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
-bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
-bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
-bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-if [ "$CONFIG_SMP" != "y" ]; then
-   bool 'Run uncached' CONFIG_MIPS_UNCACHED
-fi
-endmenu
-
-source lib/Config.in
+source arch/mips/config-shared.in
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig linux-2.4.20-pre7/arch/mips64/defconfig
--- linux-2.4.20-pre6/arch/mips64/defconfig	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,8 +18,32 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
@@ -29,38 +54,58 @@
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
-CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
-# CONFIG_MIPS_INSANE_LARGE is not set
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_MIPS_INSANE_LARGE 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
@@ -71,10 +116,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -107,6 +154,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -298,6 +346,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -341,6 +390,15 @@
 # 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
@@ -394,11 +452,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -411,6 +464,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -428,6 +483,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -458,6 +516,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -472,7 +531,6 @@
 # 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
@@ -492,10 +550,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -511,17 +575,16 @@
 # 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-atlas linux-2.4.20-pre7/arch/mips64/defconfig-atlas
--- linux-2.4.20-pre6/arch/mips64/defconfig-atlas	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig-atlas	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,41 +18,89 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 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=y
+# CONFIG_MIPS_MAGNUM_4000 is not set
 # CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO 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_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM 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_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_BOARD_SCACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # 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
@@ -59,13 +108,15 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -99,6 +150,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -115,8 +167,9 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK_DEV=y
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -302,6 +355,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -348,6 +402,15 @@
 # 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
@@ -401,11 +464,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -418,6 +476,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -435,6 +495,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -465,6 +528,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -478,7 +542,6 @@
 # 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
@@ -489,6 +552,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -504,18 +572,17 @@
 # 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-ip22 linux-2.4.20-pre7/arch/mips64/defconfig-ip22
--- linux-2.4.20-pre6/arch/mips64/defconfig-ip22	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig-ip22	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -19,47 +20,98 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO 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_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=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_SWAP_IO_SPACE=y
+CONFIG_IRQ_CPU=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
 CONFIG_SGI=y
-CONFIG_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_BOARD_SCACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
 CONFIG_ARC_CONSOLE=y
+# CONFIG_IP22_EISA 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
@@ -70,10 +122,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -106,6 +160,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -185,6 +240,13 @@
 # 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
@@ -287,6 +349,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -333,6 +396,15 @@
 # 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
@@ -381,7 +453,6 @@
 # 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
@@ -392,6 +463,7 @@
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 CONFIG_INDYDOG=y
+# CONFIG_AMD7XX_TCO is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -406,11 +478,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # SGI Character devices
 #
 CONFIG_SGI_NEWPORT_CONSOLE=y
@@ -430,6 +497,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -447,6 +516,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -477,6 +549,7 @@
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -490,7 +563,6 @@
 # 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
@@ -510,10 +582,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Console drivers
 #
 # CONFIG_VGA_CONSOLE is not set
@@ -548,18 +626,15 @@
 # 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_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_MIPS_UNCACHED is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-ip27 linux-2.4.20-pre7/arch/mips64/defconfig-ip27
--- linux-2.4.20-pre6/arch/mips64/defconfig-ip27	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig-ip27	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,8 +18,32 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
@@ -29,38 +54,58 @@
 # CONFIG_REPLICATE_EXHANDLERS is not set
 CONFIG_SMP=y
 # CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_SB1250 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
-CONFIG_MAPPED_PCI_IO=y
 CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 CONFIG_L1_CACHE_SHIFT=7
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
-# CONFIG_MIPS_INSANE_LARGE is not set
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD is not set
+# CONFIG_MIPS_INSANE_LARGE 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
@@ -71,10 +116,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -107,6 +154,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -298,6 +346,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -341,6 +390,15 @@
 # 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
@@ -394,11 +452,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -411,6 +464,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -428,6 +483,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -458,6 +516,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -472,7 +531,6 @@
 # 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
@@ -492,10 +550,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -511,17 +575,16 @@
 # 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-ip32 linux-2.4.20-pre7/arch/mips64/defconfig-ip32
--- linux-2.4.20-pre6/arch/mips64/defconfig-ip32	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig-ip32	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,45 +18,90 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO 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_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_BOOT_ELF32=y
+CONFIG_ARC_MEMORY=y
 CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NONCOHERENT_IO=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_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_BOARD_SCACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+# CONFIG_FORWARD_KEYBOARD 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_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
 # CONFIG_HOTPLUG is not set
@@ -66,10 +112,12 @@
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 CONFIG_BINFMT_MISC=y
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -102,6 +150,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -312,6 +361,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -358,6 +408,15 @@
 # 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
@@ -415,11 +474,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -432,6 +486,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -449,6 +505,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -479,6 +538,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -493,7 +553,6 @@
 # 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,10 +568,16 @@
 CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -528,18 +593,17 @@
 # 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=y
 CONFIG_MIPS_UNCACHED=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-malta linux-2.4.20-pre7/arch/mips64/defconfig-malta
--- linux-2.4.20-pre6/arch/mips64/defconfig-malta	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig-malta	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,7 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
@@ -17,33 +18,79 @@
 #
 # Machine selection
 #
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 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=y
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO 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_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
+CONFIG_HAVE_STD_PC_SERIAL_PORT=y
 CONFIG_I8259=y
 CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE=y
+CONFIG_PC_KEYB=y
+CONFIG_PCI=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
 CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_SB1 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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # General setup
@@ -53,6 +100,7 @@
 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
@@ -60,13 +108,15 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_MIPS32_COMPAT=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -100,6 +150,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -303,6 +354,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -349,6 +401,15 @@
 # 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
@@ -402,11 +463,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -419,6 +475,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
@@ -436,6 +494,9 @@
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -466,6 +527,7 @@
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -479,7 +541,6 @@
 # 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
@@ -490,6 +551,11 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -505,18 +571,17 @@
 # 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-sb1250-swarm linux-2.4.20-pre7/arch/mips64/defconfig-sb1250-swarm
--- linux-2.4.20-pre6/arch/mips64/defconfig-sb1250-swarm	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/defconfig-sb1250-swarm	Thu Sep 12 20:01:40 2002
@@ -2,82 +2,138 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
 CONFIG_MIPS64=y
 
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
 
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+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_PB1100 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_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
 CONFIG_SIBYTE_SB1250=y
-# CONFIG_PCI is not set
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+# CONFIG_SIBYTE_CFE_CONSOLE 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_PCI is not set
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_BOOT_ELF32=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_DUMMY_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
-CONFIG_CFE=y
-CONFIG_SIBYTE_SB1250=y
-CONFIG_L1_CACHE_SHIFT=5
+CONFIG_BOOT_ELF32=y
+# CONFIG_MIPS_AU1000 is not set
 
 #
 # CPU selection
 #
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX 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_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
 # CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
 CONFIG_CPU_SB1=y
+CONFIG_CPU_SB1_PASS_1=y
+# CONFIG_CPU_SB1_PASS_2 is not set
+# CONFIG_CPU_SB1_PASS_2_2 is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_SB1_CACHE_ERROR=y
+CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y
+# CONFIG_SB1_CERR_SPIN is not set
 CONFIG_VTAG_ICACHE=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
+CONFIG_CPU_HAS_SYNC=y
 
 #
 # 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 is not set
+CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL 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_MIPS32_COMPAT=y
-CONFIG_BINFMT_ELF32=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -110,6 +166,7 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -134,14 +191,15 @@
 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_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
 
 #
@@ -156,6 +214,14 @@
 # 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
@@ -175,6 +241,13 @@
 # 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
@@ -192,13 +265,13 @@
 # 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
@@ -216,6 +289,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -223,6 +297,7 @@
 # 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
@@ -237,6 +312,8 @@
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
 
 #
 # Wan interfaces
@@ -259,6 +336,15 @@
 # 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
@@ -273,7 +359,9 @@
 # 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_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -282,14 +370,14 @@
 # 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
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -334,11 +422,6 @@
 # CONFIG_DRM is not set
 
 #
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -351,9 +434,11 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD 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
@@ -363,11 +448,14 @@
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -377,11 +465,11 @@
 # 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
-CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
@@ -395,9 +483,10 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
+# CONFIG_ROOT_NFS is not set
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -412,30 +501,21 @@
 # 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
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # Sound
 #
 # CONFIG_SOUND is not set
@@ -451,17 +531,14 @@
 # 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_DEBUG is not set
 # CONFIG_MAGIC_SYSRQ is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/defconfig-sead linux-2.4.20-pre7/arch/mips64/defconfig-sead
--- linux-2.4.20-pre6/arch/mips64/defconfig-sead	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips64/defconfig-sead	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,361 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+# CONFIG_MIPS32 is not set
+CONFIG_MIPS64=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_PB1100 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_MIPS_SEAD=y
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G 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_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_L1_CACHE_SHIFT=5
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_PCI is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_SB1 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
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_NET is not set
+# 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 is not set
+# 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_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=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=y
+CONFIG_BLK_DEV_RAM_SIZE=18432
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# MIPS initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK 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
+
+#
+# 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
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO 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=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD 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
+
+#
+# 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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG 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_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS 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
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_ZISOFS_FS 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_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB 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
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/Makefile linux-2.4.20-pre7/arch/mips64/kernel/Makefile
--- linux-2.4.20-pre6/arch/mips64/kernel/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/Makefile	Thu Sep 12 20:01:40 2002
@@ -12,11 +12,12 @@
 
 O_TARGET := kernel.o
 
-export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o
+export-objs	= irq.o mips64_ksyms.o pci-dma.o setup.o smp.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-y		:= branch.o cpu-probe.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
@@ -30,6 +31,6 @@
 obj-y				+= pci-dma.o
 endif
 
-CFLAGS_r4k_genex.o := -P
+AFLAGS_r4k_genex.o := -P
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/binfmt_elf32.c linux-2.4.20-pre7/arch/mips64/kernel/binfmt_elf32.c
--- linux-2.4.20-pre6/arch/mips64/kernel/binfmt_elf32.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/binfmt_elf32.c	Thu Sep 12 20:01:40 2002
@@ -27,8 +27,26 @@
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
-#define elf_check_arch(x)	\
-	((x)->e_machine == EM_MIPS)
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr)						\
+({									\
+	int __res = 1;							\
+	struct elfhdr *__h = (hdr);					\
+									\
+	if (__h->e_machine != EM_MIPS)					\
+		__res = 0;						\
+	if (__h->e_ident[EI_CLASS] != ELFCLASS32)			\
+		__res = 0;						\
+	if ((__h->e_flags & EF_MIPS_ABI2) != 0)				\
+		__res = 0;						\
+	if (((__h->e_flags & EF_MIPS_ABI) != 0) &&			\
+	    ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))		\
+		__res = 0;						\
+									\
+	__res;								\
+})
 
 #define TASK32_SIZE		0x80000000UL
 #undef ELF_ET_DYN_BASE
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/cpu-probe.c linux-2.4.20-pre7/arch/mips64/kernel/cpu-probe.c
--- linux-2.4.20-pre6/arch/mips64/kernel/cpu-probe.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips64/kernel/cpu-probe.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,489 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <asm/bugs.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+/*
+ * 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;
+
+static void r3081_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
+}
+
+static void r39xx_wait(void)
+{
+	unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+	write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT);
+}
+
+static void r4k_wait(void)
+{
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		".set\tmips0");
+}
+
+void au1k_wait(void)
+{
+#ifdef CONFIG_PM
+	/* using the wait instruction makes CP0 counter unusable */
+	__asm__(".set\tmips3\n\t"
+		"wait\n\t"
+		"nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0");
+#else
+	__asm__("nop\n\t" "nop\n\t");
+#endif
+}
+
+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;
+	case CPU_AU1000:
+	case CPU_AU1100:
+	case CPU_AU1500:
+		cpu_wait = au1k_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.
+ * 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;
+}
+
+/*
+ * 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 = {
+    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;
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+
+__init void cpu_probe(void)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG);
+	unsigned long config1;
+
+        if (config0 & (1 << 31)) {
+		/* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */
+		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;
+#if defined(CONFIG_CPU_MIPS64)
+			mips_cpu.options |= MIPS_CPU_32FPR;
+#endif
+		}
+		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_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			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_NOFPUEX;
+			if (cpu_has_fpu())
+				mips_cpu.options |= MIPS_CPU_FPU;
+			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:
+			switch (mips_cpu.processor_id & 0xf0) {
+#ifndef CONFIG_VR4181
+			case PRID_REV_VR4111:
+				mips_cpu.cputype = CPU_VR4111;
+				break;
+#else
+			case PRID_REV_VR4181:
+				mips_cpu.cputype = CPU_VR4181;
+				break;
+#endif
+			case PRID_REV_VR4121:
+				mips_cpu.cputype = CPU_VR4121;
+				break;
+			case PRID_REV_VR4122:
+				if ((mips_cpu.processor_id & 0xf) < 0x3)
+					mips_cpu.cputype = CPU_VR4122;
+				else
+					mips_cpu.cputype = CPU_VR4181A;
+				break;
+			case PRID_REV_VR4131:
+				mips_cpu.cputype = CPU_VR4131;
+				mips_cpu.icache.ways = 2;
+				mips_cpu.dcache.ways = 2;
+				break;
+			default:
+				printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+				mips_cpu.cputype = CPU_VR41XX;
+				break;
+			}
+                        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 weird 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;
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+	case PRID_COMP_MIPS:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_4KC:
+			mips_cpu.cputype = CPU_4KC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KEC:
+			mips_cpu.cputype = CPU_4KEC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			break;
+		case PRID_IMP_4KSC:
+			mips_cpu.cputype = CPU_4KSC;
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+			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;
+			break;
+		default:
+			mips_cpu.cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
+	case PRID_COMP_ALCHEMY:
+		switch (mips_cpu.processor_id & 0xff00) {
+		case PRID_IMP_AU1_REV1:
+		case PRID_IMP_AU1_REV2:
+			switch ((mips_cpu.processor_id >> 24) & 0xff) {
+			case 0:
+ 				mips_cpu.cputype = CPU_AU1000;
+				break;
+			case 1:
+				mips_cpu.cputype = CPU_AU1500;
+				break;
+			case 2:
+				mips_cpu.cputype = CPU_AU1100;
+				break;
+			default:
+				panic("Unknown Au Core!");
+				break;
+			}
+			mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+ 			break;
+		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.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_cpu.cputype = CPU_UNKNOWN;
+	}
+	if (mips_cpu.options & MIPS_CPU_FPU)
+		mips_cpu.fpu_id = cpu_get_fpu_id();
+}
+
+__init 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);
+}
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/entry.S linux-2.4.20-pre7/arch/mips64/kernel/entry.S
--- linux-2.4.20-pre6/arch/mips64/kernel/entry.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/entry.S	Thu Sep 12 20:01:40 2002
@@ -12,11 +12,9 @@
 #include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/offset.h>
 #include <asm/stackframe.h>
 
-/* This duplicates the definition from <linux/sched.h> */
-#define PT_TRACESYS	0x00000002		/* tracing system calls */
-
 #define KU_USER 0x10
 
 		.text
@@ -24,8 +22,8 @@
 FEXPORT(ret_from_fork)
 		move	a0, v0			# prev
 		jal	schedule_tail
-		lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-		andi	t0, PT_TRACESYS
+		ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
+		andi	t0, _PT_TRACESYS
 		bnez	t0, tracesys_exit
 		j	ret_from_sys_call
 
@@ -40,13 +38,14 @@
 		bnez	t0, ret_from_sys_call
 		j	restore_all
 
-reschedule:	jal	schedule 
+reschedule:	jal	schedule
 
 FEXPORT(ret_from_sys_call)
 		mfc0	t0, CP0_STATUS	# need_resched and signals atomic test
 		ori	t0, t0, 1
 		xori	t0, t0, 1
 		mtc0	t0, CP0_STATUS
+		SSNOP; SSNOP; SSNOP
 
 		ld	v0, TASK_NEED_RESCHED($28)
 		lw	v1, TASK_SIGPENDING($28)
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/head.S linux-2.4.20-pre7/arch/mips64/kernel/head.S
--- linux-2.4.20-pre6/arch/mips64/kernel/head.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/head.S	Thu Sep 12 20:01:40 2002
@@ -26,7 +26,7 @@
 #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
 	/* We get launched at a XKPHYS address but the kernel is linked to
 	   run at a KSEG0 address, so jump there.  */
-	la	t0, \@f
+	PTR_LA	t0, \@f
 	jr	t0
 \@:
 #endif
@@ -105,10 +105,23 @@
 
 	CLI					# disable interrupts
 
-	la	$28, init_task_union		# init current pointer
+	PTR_LA	$28, init_task_union		# init current pointer
 	daddiu	sp, $28, KERNEL_STACK_SIZE-32
 	set_saved_sp	sp, t0
 
+	/* 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().
+	 */
+	PTR_LA	t0, _edata
+	sd	zero, (t0)
+	PTR_LA	t1, (_end - 8)
+1:
+	daddiu	t0, 8
+	sd	zero, (t0)
+	bne	t0, t1, 1b
+
 	dsubu	sp, 4*SZREG			# init stack pointer
 
 	j	init_arch
@@ -117,7 +130,7 @@
 #ifdef CONFIG_SMP
 /*
  * SMP slave cpus entry point.  Board specific code for bootstrap calls this
- * function after setting up the stack and gp registers. 
+ * function after setting up the stack and gp registers.
  */
 NESTED(smp_bootstrap, 16, sp)
 #ifdef CONFIG_SGI_IP27
@@ -171,7 +184,7 @@
 	page	swapper_pg_dir, 1
 	page	invalid_pte_table, 0
 	page	invalid_pmd_table, 1
-	page	kptbl, KPTBL_PAGE_ORDER
+	page	kptbl, _PGD_ORDER
 	.globl	ekptbl
 	page	kpmdtbl, 0
 ekptbl:
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/i8259.c linux-2.4.20-pre7/arch/mips64/kernel/i8259.c
--- linux-2.4.20-pre6/arch/mips64/kernel/i8259.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/i8259.c	Thu Sep 12 20:01:40 2002
@@ -42,7 +42,7 @@
 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 */
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/ioctl32.c linux-2.4.20-pre7/arch/mips64/kernel/ioctl32.c
--- linux-2.4.20-pre6/arch/mips64/kernel/ioctl32.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/ioctl32.c	Thu Sep 12 20:01:40 2002
@@ -10,12 +10,18 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/if.h>
 #include <linux/mm.h>
 #include <linux/mtio.h>
 #include <linux/init.h>
 #include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/if_pppox.h>
+#include <linux/cdrom.h>
+#include <linux/loop.h>
 #include <linux/vt.h>
 #include <linux/kd.h>
 #include <linux/netdevice.h>
@@ -27,6 +33,7 @@
 #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>
@@ -34,6 +41,8 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
+#include <linux/rtc.h>
+
 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)
@@ -41,7 +50,7 @@
 	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);
@@ -197,7 +206,7 @@
 
 	old_fs = get_fs();
 	set_fs (KERNEL_DS);
-	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);	
+	err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc);
 	set_fs (old_fs);
 	if (err)
 		goto out;
@@ -224,28 +233,26 @@
 	return err;
 }
 
-static inline int dev_ifsioc(unsigned int fd, unsigned int cmd,
-			     unsigned long arg)
+static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct ifreq32 *uifr = (struct ifreq32 *)arg;
 	struct ifreq ifr;
 	mm_segment_t old_fs;
 	int err;
 	
 	switch (cmd) {
 	case SIOCSIFMAP:
-		err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name));
-		err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
-		err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
-		err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
-		err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
-		err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
-		err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
+		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, uifr, sizeof(struct ifreq32)))
+		if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
 			return -EFAULT;
 		break;
 	}
@@ -266,17 +273,17 @@
 		case SIOCGIFDSTADDR:
 		case SIOCGIFNETMASK:
 		case SIOCGIFTXQLEN:
-			if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32)))
+			if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32)))
 				return -EFAULT;
 			break;
 		case SIOCGIFMAP:
-			err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name));
-			err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start));
-			err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end));
-			err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr));
-			err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq));
-			err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma));
-			err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port));
+			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;
@@ -313,7 +320,7 @@
 	u32 rtdev;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-	
+
 	ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr));
 	ret |= __get_user (r.rt_flags, &(ur->rt_flags));
 	ret |= __get_user (r.rt_metric, &(ur->rt_metric));
@@ -411,7 +418,7 @@
 	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);
@@ -430,7 +437,7 @@
 		set_fs (old_fs);
 	default:
 		return -EINVAL;
-	}                                        
+	}
 	return err;
 }
 
@@ -699,7 +706,95 @@
 	IOCTL32_DEFAULT(SIOCDRARP),
 	IOCTL32_DEFAULT(SIOCADDDLCI),
 	IOCTL32_DEFAULT(SIOCDELDLCI),
+	/* SG stuff */
+	IOCTL32_DEFAULT(SG_SET_TIMEOUT),
+	IOCTL32_DEFAULT(SG_GET_TIMEOUT),
+	IOCTL32_DEFAULT(SG_EMULATED_HOST),
+	IOCTL32_DEFAULT(SG_SET_TRANSFORM),
+	IOCTL32_DEFAULT(SG_GET_TRANSFORM),
+	IOCTL32_DEFAULT(SG_SET_RESERVED_SIZE),
+	IOCTL32_DEFAULT(SG_GET_RESERVED_SIZE),
+	IOCTL32_DEFAULT(SG_GET_SCSI_ID),
+	IOCTL32_DEFAULT(SG_SET_FORCE_LOW_DMA),
+	IOCTL32_DEFAULT(SG_GET_LOW_DMA),
+	IOCTL32_DEFAULT(SG_SET_FORCE_PACK_ID),
+	IOCTL32_DEFAULT(SG_GET_PACK_ID),
+	IOCTL32_DEFAULT(SG_GET_NUM_WAITING),
+	IOCTL32_DEFAULT(SG_SET_DEBUG),
+	IOCTL32_DEFAULT(SG_GET_SG_TABLESIZE),
+	IOCTL32_DEFAULT(SG_GET_COMMAND_Q),
+	IOCTL32_DEFAULT(SG_SET_COMMAND_Q),
+	IOCTL32_DEFAULT(SG_GET_VERSION_NUM),
+	IOCTL32_DEFAULT(SG_NEXT_CMD_LEN),
+	IOCTL32_DEFAULT(SG_SCSI_RESET),
+	IOCTL32_DEFAULT(SG_IO),
+	IOCTL32_DEFAULT(SG_GET_REQUEST_TABLE),
+	IOCTL32_DEFAULT(SG_SET_KEEP_ORPHAN),
+	IOCTL32_DEFAULT(SG_GET_KEEP_ORPHAN),
+	/* PPP stuff */
+	IOCTL32_DEFAULT(PPPIOCGFLAGS),
+	IOCTL32_DEFAULT(PPPIOCSFLAGS),
+	IOCTL32_DEFAULT(PPPIOCGASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCSASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCGUNIT),
+	IOCTL32_DEFAULT(PPPIOCGRASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCSRASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCGMRU),
+	IOCTL32_DEFAULT(PPPIOCSMRU),
+	IOCTL32_DEFAULT(PPPIOCSMAXCID),
+	IOCTL32_DEFAULT(PPPIOCGXASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCSXASYNCMAP),
+	IOCTL32_DEFAULT(PPPIOCXFERUNIT),
+	IOCTL32_DEFAULT(PPPIOCGNPMODE),
+	IOCTL32_DEFAULT(PPPIOCSNPMODE),
+	IOCTL32_DEFAULT(PPPIOCGDEBUG),
+	IOCTL32_DEFAULT(PPPIOCSDEBUG),
+	IOCTL32_DEFAULT(PPPIOCNEWUNIT),
+	IOCTL32_DEFAULT(PPPIOCATTACH),
+	IOCTL32_DEFAULT(PPPIOCGCHAN),
+	/* PPPOX */
+	IOCTL32_DEFAULT(PPPOEIOCSFWD),
+	IOCTL32_DEFAULT(PPPOEIOCDFWD),
+	/* CDROM stuff */
+	IOCTL32_DEFAULT(CDROMPAUSE),
+	IOCTL32_DEFAULT(CDROMRESUME),
+	IOCTL32_DEFAULT(CDROMPLAYMSF),
+	IOCTL32_DEFAULT(CDROMPLAYTRKIND),
+	IOCTL32_DEFAULT(CDROMREADTOCHDR),
+	IOCTL32_DEFAULT(CDROMREADTOCENTRY),
+	IOCTL32_DEFAULT(CDROMSTOP),
+	IOCTL32_DEFAULT(CDROMSTART),
+	IOCTL32_DEFAULT(CDROMEJECT),
+	IOCTL32_DEFAULT(CDROMVOLCTRL),
+	IOCTL32_DEFAULT(CDROMSUBCHNL),
+	IOCTL32_DEFAULT(CDROMEJECT_SW),
+	IOCTL32_DEFAULT(CDROMMULTISESSION),
+	IOCTL32_DEFAULT(CDROM_GET_MCN),
+	IOCTL32_DEFAULT(CDROMRESET),
+	IOCTL32_DEFAULT(CDROMVOLREAD),
+	IOCTL32_DEFAULT(CDROMSEEK),
+	IOCTL32_DEFAULT(CDROMPLAYBLK),
+	IOCTL32_DEFAULT(CDROMCLOSETRAY),
+	IOCTL32_DEFAULT(CDROM_SET_OPTIONS),
+	IOCTL32_DEFAULT(CDROM_CLEAR_OPTIONS),
+	IOCTL32_DEFAULT(CDROM_SELECT_SPEED),
+	IOCTL32_DEFAULT(CDROM_SELECT_DISC),
+	IOCTL32_DEFAULT(CDROM_MEDIA_CHANGED),
+	IOCTL32_DEFAULT(CDROM_DRIVE_STATUS),
+	IOCTL32_DEFAULT(CDROM_DISC_STATUS),
+	IOCTL32_DEFAULT(CDROM_CHANGER_NSLOTS),
+	IOCTL32_DEFAULT(CDROM_LOCKDOOR),
+	IOCTL32_DEFAULT(CDROM_DEBUG),
+	IOCTL32_DEFAULT(CDROM_GET_CAPABILITY),
+	/* DVD ioctls */
+	IOCTL32_DEFAULT(DVD_READ_STRUCT),
+	IOCTL32_DEFAULT(DVD_WRITE_STRUCT),
+	IOCTL32_DEFAULT(DVD_AUTH),
+	/* Big L */
+	IOCTL32_DEFAULT(LOOP_SET_FD),
+	IOCTL32_DEFAULT(LOOP_CLR_FD),
 
+	/* And these ioctls need translation */
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
 	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
@@ -727,6 +822,9 @@
 	IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc),
+	IOCTL32_HANDLER(SIOCGPPPSTATS, dev_ifsioc),
+	IOCTL32_HANDLER(SIOCGPPPCSTATS, dev_ifsioc),
+	IOCTL32_HANDLER(SIOCGPPPVER, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc),
 	IOCTL32_HANDLER(SIOCADDRT, routing_ioctl),
@@ -834,7 +932,25 @@
 	IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC),
 	IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER),
 	IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
-	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE)
+	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE),
+
+	/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+	IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */
+	IOCTL32_DEFAULT(_IOW('p', 21, int[7])), /* RTCSET */
+	IOCTL32_DEFAULT(RTC_AIE_ON),
+	IOCTL32_DEFAULT(RTC_AIE_OFF),
+	IOCTL32_DEFAULT(RTC_UIE_ON),
+	IOCTL32_DEFAULT(RTC_UIE_OFF),
+	IOCTL32_DEFAULT(RTC_PIE_ON),
+	IOCTL32_DEFAULT(RTC_PIE_OFF),
+	IOCTL32_DEFAULT(RTC_WIE_ON),
+	IOCTL32_DEFAULT(RTC_WIE_OFF),
+	IOCTL32_DEFAULT(RTC_ALM_SET),
+	IOCTL32_DEFAULT(RTC_ALM_READ),
+	IOCTL32_DEFAULT(RTC_RD_TIME),
+	IOCTL32_DEFAULT(RTC_SET_TIME),
+	IOCTL32_DEFAULT(RTC_WKALM_SET),
+	IOCTL32_DEFAULT(RTC_WKALM_RD)
 };
 
 #define NR_IOCTL32_HANDLERS	(sizeof(ioctl32_handler_table) /	\
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/irq.c linux-2.4.20-pre7/arch/mips64/kernel/irq.c
--- linux-2.4.20-pre6/arch/mips64/kernel/irq.c	Thu Sep 12 20:01:31 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/irq.c	Thu Sep 12 20:01:40 2002
@@ -31,6 +31,8 @@
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
+static void register_irq_proc (unsigned int irq);
+
 /*
  * Special irq handlers.
  */
@@ -87,7 +89,7 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_desc[i].action;
-		if (!action) 
+		if (!action)
 			continue;
 		p += sprintf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
@@ -198,12 +200,12 @@
 }
 
 /*
- * A global "cli()" while in an interrupt context turns into just a local 
- * cli(). Interrupts should use spinlocks for the (very unlikely) case that 
+ * 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 
+ *
+ * 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).
  */
 
@@ -317,9 +319,9 @@
  * 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. 
+ * controller lock.
  */
- 
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -330,7 +332,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void inline disable_irq_nosync(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -356,7 +358,7 @@
  *
  *	This function may be called - with care - from IRQ context.
  */
- 
+
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
@@ -377,7 +379,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void enable_irq(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -412,7 +414,7 @@
  */
 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
@@ -472,7 +474,7 @@
 		spin_unlock(&desc->lock);
 		handle_IRQ_event(irq, regs, action);
 		spin_lock(&desc->lock);
-		
+
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -502,7 +504,7 @@
  *	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 
+ *	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.
  *
@@ -522,10 +524,10 @@
  *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
  *
  */
- 
-int request_irq(unsigned int irq, 
+
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
@@ -580,12 +582,12 @@
  *	does not return until any executing interrupts for this IRQ
  *	have completed.
  *
- *	This function may be called from interrupt context. 
+ *	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;
@@ -646,7 +648,7 @@
  *	and a mask of potential interrupt lines is returned.
  *
  */
- 
+
 unsigned long probe_irq_on(void)
 {
 	unsigned int i;
@@ -655,15 +657,15 @@
 	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. 
+	 * 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) 
+		if (!irq_desc[i].action)
 			irq_desc[i].handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
@@ -725,7 +727,7 @@
  * 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
@@ -787,7 +789,7 @@
  *	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;
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/irq_cpu.c linux-2.4.20-pre7/arch/mips64/kernel/irq_cpu.c
--- linux-2.4.20-pre6/arch/mips64/kernel/irq_cpu.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/irq_cpu.c	Thu Sep 12 20:01:40 2002
@@ -2,6 +2,8 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
+ * Copyright (C) 2001 Ralf Baechle
+ *
  * This file define the irq handler for MIPS CPU interrupts.
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -13,8 +15,11 @@
 /*
  * 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.
+ * device).  The first two are software interrupts which we don't really
+ * use or support.  The last one is usually cpu timer interrupt if a counter
+ * register is present.
+ *
+ * Don't even think about using this on SMP.  You have been warned.
  *
  * This file exports one global function:
  *	mips_cpu_irq_init(u32 irq_base);
@@ -24,18 +29,37 @@
 #include <linux/kernel.h>
 
 #include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int mips_cpu_irq_base;
+
+static inline void unmask_mips_irq(unsigned int irq)
+{
+	clear_cp0_cause(0x100 << (irq - mips_cpu_irq_base));
+	set_cp0_status(0x100 << (irq - mips_cpu_irq_base));
+}
 
-static int mips_cpu_irq_base = -1;
+static inline void mask_mips_irq(unsigned int irq)
+{
+	clear_cp0_status(0x100 << (irq - mips_cpu_irq_base));
+}
 
-static void mips_cpu_irq_enable(unsigned int irq)
+static inline 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));
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_mips_irq(irq);
+	local_irq_restore(flags);
 }
 
 static void mips_cpu_irq_disable(unsigned int irq)
 {
-	clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8));
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_mips_irq(irq);
+	local_irq_restore(flags);
 }
 
 static unsigned int mips_cpu_irq_startup(unsigned int irq)
@@ -47,21 +71,22 @@
 
 #define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
 
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for mips_cpu_irq_end.
+ */
 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)
-	 */
+	/* Only necessary for soft interrupts */
 	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);
+	mask_mips_irq(irq);
 }
 
 static void mips_cpu_irq_end(unsigned int irq)
 {
-	if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		mips_cpu_irq_enable(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_mips_irq(irq);
 }
 
 static hw_irq_controller mips_cpu_irq_controller = {
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/linux32.c linux-2.4.20-pre7/arch/mips64/kernel/linux32.c
--- linux-2.4.20-pre6/arch/mips64/kernel/linux32.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/linux32.c	Thu Sep 12 20:01:40 2002
@@ -1,10 +1,11 @@
-/* 
+/*
  * Conversion between 32-bit and 64-bit native system calls.
  *
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
  * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
  */
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/file.h>
@@ -12,6 +13,7 @@
 #include <linux/highuid.h>
 #include <linux/dirent.h>
 #include <linux/resource.h>
+#include <linux/filter.h>
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/poll.h>
@@ -21,6 +23,7 @@
 #include <linux/shm.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
+#include <linux/icmpv6.h>
 #include <linux/sysctl.h>
 #include <linux/utime.h>
 #include <linux/utsname.h>
@@ -34,8 +37,16 @@
 #include <asm/mman.h>
 #include <asm/ipc.h>
 
-
+/* Use this to get at 32-bit user passed pointers. */
+/* 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)((int)__x))
 
 #ifdef __MIPSEB__
 #define merge_64(r1,r2)	((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
@@ -202,7 +213,7 @@
 	mm_segment_t old_fs;
 	int ret;
 	char *filenam;
-	
+
 	if (!times)
 		return sys_utime(filename, NULL);
 	if (get_user (t.actime, &times->actime) ||
@@ -212,7 +223,7 @@
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		old_fs = get_fs();
-		set_fs (KERNEL_DS); 
+		set_fs (KERNEL_DS);
 		ret = sys_utime(filenam, &t);
 		set_fs (old_fs);
 		putname (filenam);
@@ -251,7 +262,7 @@
  * memory to free pages in kernel mem. These are in a format ready
  * to be put directly into the top of new user memory.
  */
-int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm) 
+int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
 {
 	while (argc-- > 0) {
 		u32 str;
@@ -259,13 +270,13 @@
 		unsigned long pos;
 
 		if (get_user(str, argv+argc) || !str ||
-		     !(len = strnlen_user((char *)A(str), bprm->p))) 
+		     !(len = strnlen_user((char *)A(str), bprm->p)))
 			return -EFAULT;
-		if (bprm->p < len) 
-			return -E2BIG; 
+		if (bprm->p < len)
+			return -E2BIG;
 
 		bprm->p -= len;
-		/* XXX: add architecture specific overflow check here. */ 
+		/* XXX: add architecture specific overflow check here. */
 
 		pos = bprm->p;
 		while (len > 0) {
@@ -302,7 +313,7 @@
 			kunmap(page);
 
 			if (err)
-				return -EFAULT; 
+				return -EFAULT;
 
 			pos += bytes_to_copy;
 			str += bytes_to_copy;
@@ -324,7 +335,7 @@
 	int i;
 
 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
+	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
 
 	dentry = open_namei(filename, 0, 0);
 	retval = PTR_ERR(dentry);
@@ -347,21 +358,21 @@
 	}
 
 	retval = prepare_binprm(&bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	bprm.exec = bprm.p;
 	retval = copy_strings32(bprm.envc, envp, &bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	retval = copy_strings32(bprm.argc, argv, &bprm);
-	if (retval < 0) 
-		goto out; 
+	if (retval < 0)
+		goto out;
 
 	retval = search_binary_handler(&bprm,regs);
 	if (retval >= 0)
@@ -373,8 +384,8 @@
 	if (bprm.dentry)
 		dput(bprm.dentry);
 
-	/* Assumes that free_page() can take a NULL argument. */ 
-	/* I hope this is ok for all architectures */ 
+	/* Assumes that free_page() can take a NULL argument. */
+	/* I hope this is ok for all architectures */
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++)
 		if (bprm.page[i])
 			__free_page(bprm.page[i]);
@@ -403,12 +414,14 @@
 	return error;
 }
 #else
-static int
-nargs(unsigned int arg, char **ap)
+static int nargs(unsigned int arg, char **ap)
 {
 	char *ptr;
 	int n, ret;
 
+	if (!arg)
+		return 0;
+
 	n = 0;
 	do {
 		/* egcs is stupid */
@@ -422,10 +435,11 @@
 		arg += sizeof(unsigned int);
 		n++;
 	} while (ptr);
-	return(n - 1);
+
+	return n - 1;
 }
 
-asmlinkage int 
+asmlinkage int
 sys32_execve(abi64_no_regargs, struct pt_regs regs)
 {
 	extern asmlinkage int sys_execve(abi64_no_regargs, struct pt_regs regs);
@@ -560,8 +574,8 @@
         int    ru_nswap;
         int    ru_inblock;
         int    ru_oublock;
-        int    ru_msgsnd; 
-        int    ru_msgrcv; 
+        int    ru_msgsnd;
+        int    ru_msgrcv;
         int    ru_nsignals;
         int    ru_nvcsw;
         int    ru_nivcsw;
@@ -571,7 +585,7 @@
 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);
@@ -604,8 +618,8 @@
 		int ret;
 		unsigned int status;
 		mm_segment_t old_fs = get_fs();
-	
-		set_fs(KERNEL_DS);	
+
+		set_fs(KERNEL_DS);
 		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
 		set_fs(old_fs);
 		if (put_rusage (ru, &r)) return -EFAULT;
@@ -637,7 +651,7 @@
 	struct rlimit r;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_old_getrlimit(resource, &r);
 	set_fs (old_fs);
@@ -657,7 +671,7 @@
 	int ret;
 	mm_segment_t old_fs = get_fs ();
 
-	if (resource >= RLIM_NLIMITS) return -EINVAL;	
+	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;
@@ -689,7 +703,7 @@
 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);
@@ -711,7 +725,7 @@
 	int ret;
 	struct statfs s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_statfs((const char *)path, &s);
 	set_fs (old_fs);
@@ -728,7 +742,7 @@
 	int ret;
 	struct statfs s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_fstatfs(fd, &s);
 	set_fs (old_fs);
@@ -746,7 +760,7 @@
 	struct rusage r;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_getrusage(who, &r);
 	set_fs (old_fs);
@@ -831,7 +845,7 @@
 	return 0;
 
 }
-asmlinkage unsigned long 
+asmlinkage unsigned long
 sys32_alarm(unsigned int seconds)
 {
 	struct itimerval it_new, it_old;
@@ -980,7 +994,7 @@
 	/* 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;		
+		fn = (IO_fn_t) file->f_op->write;
 	ivp = iov;
 	while (count > 0) {
 		void * base;
@@ -1222,7 +1236,7 @@
 	/*
 	 * 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. 
+	 * long-words.
 	 */
 	ret = -ENOMEM;
 	size = FDS_BYTES(n);
@@ -1293,7 +1307,7 @@
 	struct timespec t;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_sched_rr_get_interval(pid, &t);
 	set_fs (old_fs);
@@ -1305,7 +1319,7 @@
 
 
 extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
-				    struct timespec *rmtp); 
+				    struct timespec *rmtp);
 
 asmlinkage int
 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
@@ -1317,7 +1331,7 @@
 	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);
@@ -1361,75 +1375,119 @@
 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
 				     char *optval, int optlen);
 
-asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+static int do_set_attach_filter(int fd, int level, int optname,
 				char *optval, int optlen)
 {
-	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;
+	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);
+	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 ret;
+		return -EFAULT;
 	}
-	return sys_setsockopt(fd, level, optname, optval, optlen);
+
+	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;
 }
 
-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;
-};
+static int do_set_icmpv6_filter(int fd, int level, int optname,
+				char *optval, int optlen)
+{
+	struct icmp6_filter kfilter;
+	mm_segment_t old_fs;
+	int ret, i;
+
+	if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
+		return -EFAULT;
+
+
+	for (i = 0; i < 8; i += 2) {
+		u32 tmp = kfilter.data[i];
+
+		kfilter.data[i] = kfilter.data[i + 1];
+		kfilter.data[i + 1] = tmp;
+	}
+
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_setsockopt(fd, level, optname,
+			     (char *) &kfilter, sizeof(kfilter));
+	set_fs(old_fs);
+
+	return ret;
+}
+
+asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+				char *optval, int optlen)
+{
+	if (optname == SO_ATTACH_FILTER)
+		return do_set_attach_filter(fd, level, optname,
+					    optval, optlen);
+	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
+		return do_set_icmpv6_filter(fd, level, optname,
+					    optval, optlen);
+
+	return sys_setsockopt(fd, level, optname, optval, optlen);
+}
 
 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
 {
 	int err;
-	
-	err = get_user(kfl->l_type, &ufl->l_type);
+
+	if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)))
+		return -EFAULT;
+
+	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;
-	
+
+	if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)))
+		return -EFAULT;
+
 	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(0, &ufl->l_sysid);
 	err |= __put_user(kfl->l_pid, &ufl->l_pid);
+
 	return err;
 }
 
@@ -1447,7 +1505,7 @@
 			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);
@@ -1490,6 +1548,19 @@
         unsigned short  seq;
 };
 
+struct ipc64_perm32 {
+	key_t key;
+	__kernel_uid_t32 uid;
+	__kernel_gid_t32 gid;
+	__kernel_uid_t32 cuid;
+	__kernel_gid_t32 cgid;
+	__kernel_mode_t32 mode; 
+	unsigned short seq;
+	unsigned short __pad1;
+	unsigned int __unused1;
+	unsigned int __unused2;
+};
+
 struct semid_ds32 {
         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
         __kernel_time_t32 sem_otime;              /* last semop time */
@@ -1512,24 +1583,44 @@
         u32 wwait;
         u32 rwait;
         unsigned short msg_cbytes;
-        unsigned short msg_qnum;  
+        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_perm32 msg_perm;
+	__kernel_time_t32 msg_stime;
+	unsigned int __unused1;
+	__kernel_time_t32 msg_rtime;
+	unsigned int __unused2;
+	__kernel_time_t32 msg_ctime;
+	unsigned int __unused3;
+	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_perm32       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; 
+        __kernel_ipc_pid_t32    shm_cpid;
+        __kernel_ipc_pid_t32    shm_lpid;
         unsigned short          shm_nattch;
 };
 
-#define IPCOP_MASK(__x)	(1UL << (__x))
+struct ipc_kludge32 {
+	u32 msgp;
+	s32 msgtyp;
+};
 
 static int
 do_sys32_semctl(int first, int second, int third, void *uptr)
@@ -1596,21 +1687,23 @@
 	return err;
 }
 
-static int
 do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
-				    + 4, GFP_USER);
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+	struct msgbuf *p;
 	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);
 	if (err)
 		goto out;
-	err = __copy_from_user (p->mtext, &up->mtext, second);
+	err |= __copy_from_user (p->mtext, &up->mtext, second);
 	if (err)
 		goto out;
 	old_fs = get_fs ();
@@ -1619,6 +1712,7 @@
 	set_fs (old_fs);
 out:
 	kfree (p);
+
 	return err;
 }
 
@@ -1632,18 +1726,21 @@
 	int err;
 
 	if (!version) {
-		struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
-		struct ipc_kludge ipck;
+		struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
+		struct ipc_kludge32 ipck;
 
 		err = -EINVAL;
 		if (!uptr)
 			goto out;
 		err = -EFAULT;
-		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
+		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
 			goto out;
-		uptr = (void *)A(ipck.msgp);
+		uptr = (void *)AA(ipck.msgp);
 		msgtyp = ipck.msgtyp;
 	}
+
+	if (second < 0)
+		return -EINVAL;
 	err = -ENOMEM;
 	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
 	if (!p)
@@ -1668,13 +1765,12 @@
 do_sys32_msgctl (int first, int second, void *uptr)
 {
 	int err = -EINVAL, err2;
-	struct msqid_ds m;
-	struct msqid64_ds m64;
-	struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
+	struct msqid64_ds m;
+	struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
+	struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
 	mm_segment_t old_fs;
 
-	switch (second) {
-
+	switch (second & ~IPC_64) {
 	case IPC_INFO:
 	case IPC_RMID:
 	case MSG_INFO:
@@ -1682,15 +1778,30 @@
 		break;
 
 	case IPC_SET:
-		err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
-		err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
-		err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
-		err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
+			err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
+			err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
+			err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
+		} else {
+			if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
+			err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
+			err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
+			err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
+		}
 		if (err)
 			break;
 		old_fs = get_fs ();
 		set_fs (KERNEL_DS);
-		err = sys_msgctl (first, second, &m);
+		err = sys_msgctl (first, second, (struct msqid_ds *)&m);
 		set_fs (old_fs);
 		break;
 
@@ -1698,27 +1809,54 @@
 	case MSG_STAT:
 		old_fs = get_fs ();
 		set_fs (KERNEL_DS);
-		err = sys_msgctl (first, second, (void *) &m64);
+		err = sys_msgctl (first, second, (struct msqid_ds *)&m);
 		set_fs (old_fs);
-		err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
-		err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
-		err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
-		err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
-		err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
-		err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
-		err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
-		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;
+		if (second & IPC_64) {
+			if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
+			err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
+			err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
+			err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
+			err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
+			err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
+			err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
+			err2 |= __put_user(m.msg_stime, &up64->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		} else {
+			if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
+				err = -EFAULT;
+				break;
+			}
+			err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
+			err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
+			err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
+			err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
+			err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
+			err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
+			err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
+			err2 |= __put_user(m.msg_stime, &up32->msg_stime);
+			err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
+			err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
+			err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
+			err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
+			err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
+			err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
+			err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
+			if (err2)
+				err = -EFAULT;
+		}
 		break;
-
 	}
 
 	return err;
@@ -1841,7 +1979,7 @@
 
 	case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
-		err = sys_semop (first, (struct sembuf *)A(ptr),
+		err = sys_semop (first, (struct sembuf *)AA(ptr),
 				 second);
 		break;
 	case SEMGET:
@@ -1849,36 +1987,36 @@
 		break;
 	case SEMCTL:
 		err = do_sys32_semctl (first, second, third,
-				       (void *)A(ptr));
+				       (void *)AA(ptr));
 		break;
 
 	case MSGSND:
 		err = do_sys32_msgsnd (first, second, third,
-				       (void *)A(ptr));
+				       (void *)AA(ptr));
 		break;
 	case MSGRCV:
 		err = do_sys32_msgrcv (first, second, fifth, third,
-				       version, (void *)A(ptr));
+				       version, (void *)AA(ptr));
 		break;
 	case MSGGET:
 		err = sys_msgget ((key_t) first, second);
 		break;
 	case MSGCTL:
-		err = do_sys32_msgctl (first, second, (void *)A(ptr));
+		err = do_sys32_msgctl (first, second, (void *)AA(ptr));
 		break;
 
 	case SHMAT:
 		err = do_sys32_shmat (first, second, third,
-				      version, (void *)A(ptr));
+				      version, (void *)AA(ptr));
 		break;
-	case SHMDT: 
+	case SHMDT:
 		err = sys_shmdt ((char *)A(ptr));
 		break;
 	case SHMGET:
 		err = sys_shmget (first, second, third);
 		break;
 	case SHMCTL:
-		err = do_sys32_shmctl (first, second, (void *)A(ptr));
+		err = do_sys32_shmctl (first, second, (void *)AA(ptr));
 		break;
 	default:
 		err = -EINVAL;
@@ -1911,7 +2049,7 @@
 	ret = -EFAULT;
 
 	memset(&kargs, 0, sizeof (kargs));
-	
+
 	err = get_user(kargs32.name, &uargs32->name);
 	err |= __get_user(kargs32.nlen, &uargs32->nlen);
 	err |= __get_user(kargs32.oldval, &uargs32->oldval);
@@ -1973,7 +2111,7 @@
 		kfree(kargs.oldval);
 	if (kargs.newval)
 		kfree(kargs.newval);
-	return ret; 
+	return ret;
 }
 
 asmlinkage long sys32_newuname(struct new_utsname * name)
@@ -2081,7 +2219,7 @@
 /*
  *  Declare the 32-bit version of the msghdr
  */
- 
+
 struct msghdr32 {
 	unsigned int    msg_name;	/* Socket name			*/
 	int		msg_namelen;	/* Length of name		*/
@@ -2129,7 +2267,7 @@
 {
 	int size, err, ct;
 	struct iovec32 *iov32;
-	
+
 	if(m->msg_namelen)
 	{
 		if(mode==VERIFY_READ)
@@ -2138,7 +2276,7 @@
 			if(err<0)
 				goto out;
 		}
-		
+
 		m->msg_name = address;
 	} else
 		m->msg_name = NULL;
@@ -2167,7 +2305,7 @@
 }
 
 /* XXX This really belongs in some header file... -DaveM */
-#define MAX_SOCK_ADDR	128		/* 108 for Unix domain - 
+#define MAX_SOCK_ADDR	128		/* 108 for Unix domain -
 					   16 for IP, 16 for IPX,
 					   24 for IPv6,
 					   about 80 for AX.25 */
@@ -2187,13 +2325,13 @@
 	unsigned char *ctl_buf = ctl;
 	struct msghdr msg_sys;
 	int err, ctl_len, iov_size, total_len;
-	
+
 	err = -EFAULT;
 	if (shape_msg(&msg_sys, msg))
-		goto out; 
+		goto out;
 
 	sock = sockfd_lookup(fd, &err);
-	if (!sock) 
+	if (!sock)
 		goto out;
 
 	/* do not move before msg_sys is valid */
@@ -2212,7 +2350,7 @@
 
 	/* This will also move the address data into kernel space */
 	err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
-	if (err < 0) 
+	if (err < 0)
 		goto out_freeiov;
 	total_len = err;
 
@@ -2220,14 +2358,14 @@
 
 	if (msg_sys.msg_controllen > INT_MAX)
 		goto out_freeiov;
-	ctl_len = msg_sys.msg_controllen; 
-	if (ctl_len) 
+	ctl_len = msg_sys.msg_controllen;
+	if (ctl_len)
 	{
 		if (ctl_len > sizeof(ctl))
 		{
 			err = -ENOBUFS;
 			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
-			if (ctl_buf == NULL) 
+			if (ctl_buf == NULL)
 				goto out_freeiov;
 		}
 		err = -EFAULT;
@@ -2242,14 +2380,14 @@
 	err = sock_sendmsg(sock, &msg_sys, total_len);
 
 out_freectl:
-	if (ctl_buf != ctl)    
+	if (ctl_buf != ctl)
 		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
 out_freeiov:
 	if (iov != iovstack)
 		sock_kfree_s(sock->sk, iov, iov_size);
 out_put:
 	sockfd_put(sock);
-out:       
+out:
 	return err;
 }
 
@@ -2273,7 +2411,7 @@
 	/* user mode address pointers */
 	struct sockaddr *uaddr;
 	int *uaddr_len;
-	
+
 	err=-EFAULT;
 	if (shape_msg(&msg_sys, msg))
 		goto out;
@@ -2285,7 +2423,7 @@
 	err = -EINVAL;
 	if (msg_sys.msg_iovlen > UIO_MAXIOV)
 		goto out_put;
-	
+
 	/* Check whether to allocate the iovec area*/
 	err = -ENOMEM;
 	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
@@ -2299,7 +2437,7 @@
 	 *	Save the user-mode address (verify_iovec will change the
 	 *	kernel msghdr to use the kernel address space)
 	 */
-	 
+
 	uaddr = msg_sys.msg_name;
 	uaddr_len = &msg->msg_namelen;
 	err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
@@ -2309,7 +2447,7 @@
 
 	cmsg_ptr = (unsigned long)msg_sys.msg_control;
 	msg_sys.msg_flags = 0;
-	
+
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	err = sock_recvmsg(sock, &msg_sys, total_len, flags);
@@ -2325,7 +2463,7 @@
 	err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
 	if (err)
 		goto out_freeiov;
-	err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, 
+	err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
 							 &msg->msg_controllen);
 	if (err)
 		goto out_freeiov;
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/mips64_ksyms.c linux-2.4.20-pre7/arch/mips64/kernel/mips64_ksyms.c
--- linux-2.4.20-pre6/arch/mips64/kernel/mips64_ksyms.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/mips64_ksyms.c	Thu Sep 12 20:01:40 2002
@@ -39,7 +39,10 @@
 extern long __strnlen_user_asm(const char *s);
 
 EXPORT_SYMBOL(mips_machtype);
+
+#ifdef CONFIG_EISA
 EXPORT_SYMBOL(EISA_bus);
+#endif
 
 /*
  * String functions
@@ -90,21 +93,11 @@
 EXPORT_SYMBOL(invalid_pte_table);
 
 /*
- * Base address of ports for Intel style I/O.
- */
-#if defined (CONFIG_PCI) || defined (CONFIG_ISA)
-EXPORT_SYMBOL(mips_io_port_base);
-#endif
-
-/*
  * Kernel hacking ...
  */
 #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
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/pci-dma.c linux-2.4.20-pre7/arch/mips64/kernel/pci-dma.c
--- linux-2.4.20-pre6/arch/mips64/kernel/pci-dma.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/pci-dma.c	Thu Sep 12 20:01:40 2002
@@ -4,17 +4,17 @@
  * for more details.
  *
  * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000  Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2000, 2001  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/module.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)
@@ -22,24 +22,34 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
-	if (hwdev != NULL && hwdev->dma_mask != 0xffffffff)
+#ifdef CONFIG_ISA
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
+#endif
 	ret = (void *) __get_free_pages(gfp, get_order(size));
 
 	if (ret != NULL) {
 		memset(ret, 0, size);
+		*dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret));
 #ifdef CONFIG_NONCOHERENT_IO
 		dma_cache_wback_inv((unsigned long) ret, size);
-		ret = KSEG1ADDR(ret);
+		ret = UNCAC_ADDR(ret);
 #endif
-		*dma_handle = __pa(ret);
-		return ret;
 	}
-	return NULL;
+
+	return ret;
 }
 
 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));
+	unsigned long addr = (unsigned long) vaddr;
+
+#ifdef CONFIG_NONCOHERENT_IO
+	addr = CAC_ADDR(addr);
+#endif
+	free_pages(addr, get_order(size));
 }
+
+EXPORT_SYMBOL(pci_alloc_consistent);
+EXPORT_SYMBOL(pci_free_consistent);
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/proc.c linux-2.4.20-pre7/arch/mips64/kernel/proc.c
--- linux-2.4.20-pre6/arch/mips64/kernel/proc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/proc.c	Thu Sep 12 20:01:40 2002
@@ -67,7 +67,13 @@
 	[CPU_R5500]	"R5500",
 	[CPU_TX49XX]	"TX49xx",
 	[CPU_TX39XX]	"TX39xx",
-	[CPU_20KC]	"MIPS 20Kc"
+	[CPU_20KC]	"MIPS 20Kc",
+	[CPU_VR4111]	"NEC VR4111",
+	[CPU_VR4121]	"NEC VR4121",
+	[CPU_VR4122]	"NEC VR4122",
+	[CPU_VR4131]	"NEC VR4131",
+	[CPU_VR4181]	"NEC VR4181",
+	[CPU_VR4181A]	"NEC VR4181A"
 };
 
 
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/process.c linux-2.4.20-pre7/arch/mips64/kernel/process.c
--- linux-2.4.20-pre6/arch/mips64/kernel/process.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/process.c	Thu Sep 12 20:01:40 2002
@@ -29,6 +29,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/elf.h>
+#include <asm/cpu.h>
 
 ATTRIB_NORET void cpu_idle(void)
 {
@@ -53,8 +54,10 @@
 {
 	/* Forget lazy fpu state */
 	if (IS_FPU_OWNER()) {
-		__enable_fpu();
-		__asm__ __volatile__("cfc1\t$0,$31");
+		if (mips_cpu.options & MIPS_CPU_FPU) {
+			__enable_fpu();
+			__asm__ __volatile__("cfc1\t$0,$31");
+		}
 		CLEAR_FPU_OWNER();
 	}
 }
@@ -63,8 +66,10 @@
 {
 	/* Forget lazy fpu state */
 	if (IS_FPU_OWNER()) {
-		__enable_fpu();
-		__asm__ __volatile__("cfc1\t$0,$31");
+		if (mips_cpu.options & MIPS_CPU_FPU) {
+			__enable_fpu();
+			__asm__ __volatile__("cfc1\t$0,$31");
+		}
 		CLEAR_FPU_OWNER();
 	}
 }
@@ -79,7 +84,8 @@
 	childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32;
 
 	if (IS_FPU_OWNER()) {
-		save_fp(p);
+		if (mips_cpu.options & MIPS_CPU_FPU)
+			save_fp(p);
 	}
 	/* set up new TSS. */
 	childregs = (struct pt_regs *) childksp - 1;
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/ptrace.c linux-2.4.20-pre7/arch/mips64/kernel/ptrace.c
--- linux-2.4.20-pre6/arch/mips64/kernel/ptrace.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/ptrace.c	Thu Sep 12 20:01:40 2002
@@ -84,7 +84,7 @@
 
 	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_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned int tmp;
 		int copied;
@@ -203,7 +203,7 @@
 			fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0];
 			if (child->used_math) {
 #ifndef CONFIG_SMP
-				if (last_task_used_math == child) 
+				if (last_task_used_math == child)
 					if (mips_cpu.options & MIPS_CPU_FPU) {
 						__enable_fpu();
 						save_fp(child);
@@ -245,7 +245,7 @@
 			regs->lo = data;
 			break;
 		case FPC_CSR:
-			if (mips_cpu.options & MIPS_CPU_FPU) 
+			if (mips_cpu.options & MIPS_CPU_FPU)
 				child->thread.fpu.hard.control = data;
 			else
 				child->thread.fpu.soft.sr = data;
@@ -273,8 +273,8 @@
 	}
 
 /*
- * 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 
+ * 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: {
@@ -355,7 +355,7 @@
 
 	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_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned long tmp;
 		int copied;
@@ -546,8 +546,8 @@
 	}
 
 /*
- * 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 
+ * 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: {
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/r4k_fpu.S linux-2.4.20-pre7/arch/mips64/kernel/r4k_fpu.S
--- linux-2.4.20-pre6/arch/mips64/kernel/r4k_fpu.S	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/arch/mips64/kernel/r4k_fpu.S	Thu Sep 12 20:01:40 2002
@@ -31,7 +31,7 @@
 
 	.set	noreorder
 	/* Save floating point context */
-LEAF(save_fp_context)
+LEAF(_save_fp_context)
 	mfc0	t1, CP0_STATUS
 	sll	t2, t1,5
 
@@ -79,7 +79,7 @@
 
 	jr	ra
 	 li	v0, 0					# success
-	END(save_fp_context)
+	END(_save_fp_context)
 
 /*
  * Restore FPU state:
@@ -90,7 +90,7 @@
  * frame on the current content of c0_status, not on the content of the
  * stack frame which might have been changed by the user.
  */
-LEAF(restore_fp_context)
+LEAF(_restore_fp_context)
 	mfc0	t1, CP0_STATUS
 	sll	t0, t1,5
 	bgez	t0, 1f
@@ -139,7 +139,7 @@
 	ctc1	t0, fcr31
 	jr	ra
 	 li	v0, 0					# success
-	END(restore_fp_context)
+	END(_restore_fp_context)
 
 	.type	fault@function
 	.ent	fault
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/r4k_genex.S linux-2.4.20-pre7/arch/mips64/kernel/r4k_genex.S
--- linux-2.4.20-pre6/arch/mips64/kernel/r4k_genex.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/r4k_genex.S	Thu Sep 12 20:01:40 2002
@@ -40,6 +40,9 @@
  */
 	NESTED(except_vec3_r4000, 0, sp)
 	.set	noat
+#if defined(R5432_CP0_INTERRUPT_WAR)
+	mfc0    k0, CP0_INDEX
+#endif
 	mfc0	k1, CP0_CAUSE
 	andi	k1, k1, 0x7c
 	li	k0, 31<<2
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/r4k_switch.S linux-2.4.20-pre7/arch/mips64/kernel/r4k_switch.S
--- linux-2.4.20-pre6/arch/mips64/kernel/r4k_switch.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/r4k_switch.S	Thu Sep 12 20:01:40 2002
@@ -10,7 +10,6 @@
  */
 #include <asm/asm.h>
 #include <asm/cachectl.h>
-#include <asm/current.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/offset.h>
@@ -69,6 +68,7 @@
 	li	t3, ST0_CU1
 	or	t0, t3
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 
 	beqz	a0, 2f				# Save floating point state
 	 nor	t3, zero, t3
@@ -88,11 +88,11 @@
 
 	sll	t0, t0, 5			# load new fp state
 	bgez	t0, 1f
-	 ldc1	$f0, (THREAD_FPU + 0x00)($28)
-	fpu_restore_16odd $28
+	 ldc1	$f0, (THREAD_FPU + 0x00)(a1)
+	fpu_restore_16odd a1
 1:
 	.set	reorder
-	fpu_restore_16even $28, t0		# clobbers t0
+	fpu_restore_16even a1, t0		# clobbers t0
 3:
 	jr	ra
 	END(lazy_fpu_switch)
@@ -119,15 +119,15 @@
 LEAF(restore_fp)
 	mfc0	t0, CP0_STATUS
 	sll	t1, t0, 5
-	bgez	t0, 1f				# 16 register mode?
+	bgez	t1, 1f				# 16 register mode?
 	 nop
 
-	fpu_restore_16odd $28
+	fpu_restore_16odd a0
 1:
-	.set	reorder
-	fpu_restore_16even $28, t0		# clobbers t0
+	fpu_restore_16even a0, t0		# clobbers t0
 
 	jr	ra
+	 ldc1	$f0, (THREAD_FPU + 0x00)(a0)
 	END(restore_fp)
 
 /*
@@ -145,6 +145,7 @@
 	li	t1, ST0_CU1
 	or	t0, t1
 	mtc0	t0, CP0_STATUS
+	FPU_ENABLE_HAZARD
 	sll	t0, t0, 5
 
 	li	t1, FPU_DEFAULT
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/scall_64.S linux-2.4.20-pre7/arch/mips64/kernel/scall_64.S
--- linux-2.4.20-pre6/arch/mips64/kernel/scall_64.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/scall_64.S	Thu Sep 12 20:01:40 2002
@@ -15,12 +15,7 @@
 #include <asm/regdef.h>
 #include <asm/stackframe.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).  */
+#include <asm/offset.h>
 
 #ifndef CONFIG_MIPS32_COMPAT
 #define handle_sys64 handle_sys
@@ -49,7 +44,7 @@
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
+	andi	t0, _PT_TRACESYS
 	bnez	t0, trace_a_syscall
 
 	jalr	t2			# Do The Real Thing (TM)
@@ -65,9 +60,10 @@
 
 ret_from_sys_call:
 	mfc0	t0, CP0_STATUS
-	xori	t0, t0, 1
 	ori	t0, t0, 1
+	xori	t0, t0, 1
 	mtc0	t0, CP0_STATUS
+	SSNOP; SSNOP; SSNOP
 
 	ld	t2, TASK_NEED_RESCHED($28)
 	bnez	t2, reschedule
@@ -132,6 +128,7 @@
 	j	ret_from_sys_call
 	END(handle_sys64)
 
+	.align	3
 sys_call_table:
 	PTR	sys_syscall				/* 5000 */
 	PTR	sys_exit
@@ -350,20 +347,20 @@
 	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_setxattr
+	PTR	sys_lsetxattr
+	PTR	sys_fsetxattr
+	PTR	sys_getxattr				/* 5220 */
+	PTR	sys_lgetxattr
+	PTR	sys_fgetxattr
+	PTR	sys_listxattr
+	PTR	sys_llistxattr
+	PTR	sys_flistxattr				/* 5225 */
+	PTR	sys_removexattr
+	PTR	sys_lremovexattr
+	PTR	sys_fremovexattr
 	PTR	sys_tkill, 2
-	PTR	sys_ni_syscall, 0		/* res. for sendfile64 */
+	PTR	sys_ni_syscall, 0		/* 5230 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 */
+	PTR	sys_ni_syscall, 0		/* res. for sched_getaffinity */
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/scall_o32.S linux-2.4.20-pre7/arch/mips64/kernel/scall_o32.S
--- linux-2.4.20-pre6/arch/mips64/kernel/scall_o32.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/scall_o32.S	Thu Sep 12 20:01:40 2002
@@ -16,17 +16,12 @@
 #include <linux/errno.h>
 #include <asm/current.h>
 #include <asm/mipsregs.h>
+#include <asm/offset.h>
 #include <asm/regdef.h>
 #include <asm/stackframe.h>
 #include <asm/unistd.h>
 #include <asm/sysmips.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_Linux32 + __NR_Linux32_syscalls
 
@@ -61,7 +56,7 @@
 
 stack_done:
 		ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-		andi	t0, PT_TRACESYS
+		andi	t0, _PT_TRACESYS
 		bnez	t0, trace_a_syscall
 
 		jalr	t2			# Do The Real Thing (TM)
@@ -80,6 +75,7 @@
 		ori	t0, t0, 1
 		xori	t0, t0, 1
 		mtc0	t0, CP0_STATUS
+		SSNOP; SSNOP; SSNOP
 
 		ld	t2, TASK_NEED_RESCHED($28)
 		bnez	t2, o32_reschedule
@@ -156,16 +152,20 @@
 	bltz	t0, bad_stack		# -> sp is bad
 
 	ld	t0, PT_R29(sp)		# get old user stack pointer
-	la	t1, 3f			# copy 1 to 2 arguments
+	PTR_LA	t1, 3f			# copy 1 to 2 arguments
 	sll	t3, t3, 2
 	subu	t1, t3
 	jr	t1
 
 	/* Ok, copy the args from the luser stack to the kernel stack */
+	.set	push
+	.set	noreorder
+	.set	nomacro
 1:	lw	a5, 20(t0)		# argument #6 from usp
 2:	lw	a4, 16(t0)		# argument #5 from usp
+3:	.set	pop
 
-3:	j	stack_done		# go back
+	j	stack_done		# go back
 
 	.section __ex_table,"a"
 	PTR	1b, bad_stack
@@ -222,7 +222,7 @@
 
 	/* Success, so skip usual error handling garbage.  */
 	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
-	andi	t0, PT_TRACESYS
+	andi	t0, _PT_TRACESYS
 	bnez	t0, 1f
 	b	o32_ret_from_sys_call
 
@@ -245,8 +245,74 @@
 	j	sys_sysmips
 	END(sys32_sysmips)
 
+	LEAF(sys32_syscall)
+	ld	t0, PT_R29(sp)		# user sp
+
+	sltu	v0, a0, __NR_Linux + __NR_Linux_syscalls + 1
+	beqz	v0, enosys
+
+	dsll	v0, a0, 3
+	dla	v1, sys32_syscall
+	ld	t2, (sys_call_table - (__NR_Linux32 * 8))(v0)	# function pointer
+	lbu	t3, (sys_narg_table - __NR_Linux32)(a0)	# 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
+
+	daddiu	v0, t0, 16		# v0 = usp + 16
+	daddu	t1, v0, 12		# 3 32-bit arguments
+	ld	v1, THREAD_CURDS($28)
+	or	v0, v0, t1
+	and	v1, v1, v0
+	bltz	v1, efault
+
+	move	a0, a1			# shift argument registers
+	move	a1, a2
+	move	a2, a3
+
+1:	lw	a3, 16(t0)
+2:	lw	t3, 20(t0)
+3:	lw	t1, 24(t0)
+
+	.section __ex_table,"a"
+	PTR	1b, efault
+	PTR	2b, efault
+	PTR	3b, efault
+	.previous
+
+	sw	t3, 16(sp)		# put into new stackframe
+	sw	t1, 20(sp)
+
+	bnez	t1, 1f			# zero arguments?
+	daddu	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(sys32_syscall)
+
 	.macro	syscalltable
-	sys	sys_syscall	0			/* 4000 */
+	sys	sys32_syscall	0			/* 4000 */
 	sys	sys_exit	1
 	sys	sys_fork	0
 	sys	sys_read	3
@@ -453,7 +519,7 @@
 	sys	sys_capget	2
 	sys	sys_capset	2			/* 4205 */
 	sys	sys32_sigaltstack	0
-	sys	sys_sendfile	3
+	sys	sys_sendfile	4
 	sys	sys_ni_syscall	0
 	sys	sys_ni_syscall	0
 	sys	sys_mmap2	6			/* 4210 */
@@ -470,18 +536,18 @@
 	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_setxattr	5
+	sys	sys_lsetxattr	5		/* 4225 */
+	sys	sys_fsetxattr	5
+	sys	sys_getxattr	4
+	sys	sys_lgetxattr	4
+	sys	sys_fgetxattr	4
+	sys	sys_listxattr	3		/* 4230 */
+	sys	sys_llistxattr	3
+	sys	sys_flistxattr	3
+	sys	sys_removexattr	2
+	sys	sys_lremovexattr 2
+	sys	sys_fremovexattr 2		/* 4235 */
 	sys	sys_tkill, 2
 	sys	sys_ni_syscall, 0		/* res. for sendfile64 */
 	sys	sys_ni_syscall, 0		/* res. for futex */
@@ -494,6 +560,7 @@
 	PTR	\function
 	.endm
 
+	.align	3
 sys_call_table:
 	syscalltable
 
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/setup.c linux-2.4.20-pre7/arch/mips64/kernel/setup.c
--- linux-2.4.20-pre6/arch/mips64/kernel/setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/setup.c	Thu Sep 12 20:01:40 2002
@@ -43,15 +43,6 @@
 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
@@ -66,7 +57,9 @@
 /*
  * Set if box has EISA slots.
  */
+#ifdef CONFIG_EISA
 int EISA_bus = 0;
+#endif
 
 #ifdef CONFIG_BLK_DEV_FD
 extern struct fd_ops no_fd_ops;
@@ -113,387 +106,19 @@
 extern void ip27_setup(void);
 extern void ip32_setup(void);
 
+/*
+ * 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);
 extern void load_mmu(void);
 extern ATTRIB_NORET asmlinkage void start_kernel(void);
 extern void prom_init(int, char **, char **, int *);
 
-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.
- * 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;
-#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_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;
-#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_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 init_arch(int argc, char **argv, char **envp,
 	int *prom_vec)
 {
@@ -547,7 +172,7 @@
 	int i;
 
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		printk(" memory: %08Lx @ %08Lx ",
+		printk(" memory: %016Lx @ %016Lx ",
 			(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) {
@@ -745,6 +370,9 @@
 #ifdef CONFIG_SIBYTE_SWARM
 	swarm_setup();
 #endif
+#ifdef CONFIG_MIPS_MALTA
+	malta_setup();
+#endif
 
 	strncpy(command_line, arcs_cmdline, CL_SIZE);
 	memcpy(saved_command_line, command_line, CL_SIZE);
@@ -759,25 +387,6 @@
 	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;
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/signal.c linux-2.4.20-pre7/arch/mips64/kernel/signal.c
--- linux-2.4.20-pre6/arch/mips64/kernel/signal.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/signal.c	Thu Sep 12 20:01:40 2002
@@ -32,8 +32,8 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern asmlinkage int save_fp_context(struct sigcontext *sc);
-extern asmlinkage int restore_fp_context(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
 
 extern asmlinkage void syscall_trace(void);
 
@@ -72,35 +72,6 @@
 	}
 }
 
-static inline int store_fp_context(struct sigcontext *sc)
-{
-	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));
-	__asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0));
-	err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int));
-
-	return err;
-}
-
-static inline int refill_fp_context(struct sigcontext *sc)
-{
-	int err = 0;
-
-	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));
-	return err;
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -165,7 +136,7 @@
 	}
 }
 
-asmlinkage int 
+asmlinkage int
 sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
 {
 	struct k_sigaction new_ka, old_ka;
@@ -214,6 +185,54 @@
 	return do_sigaltstack(uss, uoss, usp);
 }
 
+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.
+      */
+
+#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;
+}
+
 asmlinkage int
 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
@@ -241,15 +260,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) {
-		if (IS_FPU_OWNER()) {
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		current->used_math = 1;
-		err |= refill_fp_context(sc);
+		err |= restore_fp_context(sc);
+		goto out;
+	}
+
+	if (IS_FPU_OWNER()) {
+		/* Signal handler acquired FPU - give it back */
+		CLEAR_FPU_OWNER();
+		regs->cp0_status &= ~ST0_CU1;
+	}
+	if (current->used_math) {
+		/* Undo possible contamination of thread state */
+		err |= restore_thread_fp_context(sc);
 	}
 
+out:
 	return err;
 }
 
@@ -347,9 +375,11 @@
 static int inline setup_sigcontext(struct pt_regs *regs,
 				   struct sigcontext *sc)
 {
+	int owned_fp;
 	int err = 0;
 
 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
 #define save_gp_reg(i) do {						\
 	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
@@ -370,20 +400,27 @@
 	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
-	if (current->used_math) {	/* fp is active.  */
-		if (IS_FPU_OWNER()) {
-			lazy_fpu_switch(current, 0);
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		err |= __put_user(1, &sc->sc_ownedfp);
-		err |= store_fp_context(sc);
-		current->used_math = 0;
-	} else {
-		err |= __put_user(0, &sc->sc_ownedfp);
+	owned_fp = IS_FPU_OWNER();
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+	err |= __put_user(current->used_math, &sc->sc_used_math);
+
+	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);
+		goto out;
 	}
-	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
+	/*
+	 * Someone else has FPU.
+	 * Copy Thread context into signal context
+	 */
+	err |= save_thread_fp_context(sc);
+
+out:
 	return err;
 }
 
@@ -398,6 +435,13 @@
 	/* 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;
@@ -456,8 +500,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;
 
@@ -532,8 +577,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;
 
@@ -661,7 +707,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:
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/signal32.c linux-2.4.20-pre7/arch/mips64/kernel/signal32.c
--- linux-2.4.20-pre6/arch/mips64/kernel/signal32.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/signal32.c	Thu Sep 12 20:01:40 2002
@@ -31,8 +31,8 @@
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-extern asmlinkage int save_fp_context(struct sigcontext *sc);
-extern asmlinkage int restore_fp_context(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
 
 extern asmlinkage void syscall_trace(void);
 
@@ -63,38 +63,6 @@
 	int ss_flags;
 } stack32_t;
 
-
-static inline int store_fp_context(struct sigcontext *sc)
-{
-	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));
-	__asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0));
-	err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int));
-
-	return err;
-}
-
-static inline int refill_fp_context(struct sigcontext *sc)
-{
-	int err = 0;
-
-	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));
-	return err;
-}
-
 extern void __put_sigset_unknown_nsig(void);
 extern void __get_sigset_unknown_nsig(void);
 
@@ -289,6 +257,54 @@
 	return ret;
 }
 
+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.
+	 */
+
+#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 asmlinkage int restore_sigcontext(struct pt_regs *regs,
 					 struct sigcontext *sc)
 {
@@ -316,15 +332,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) {
-		if (IS_FPU_OWNER()) {
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		current->used_math = 1;
-		err |= refill_fp_context(sc);
+		err |= restore_fp_context(sc);
+		goto out;
+	}
+
+	if (IS_FPU_OWNER()) {
+		/* Signal handler acquired FPU - give it back */
+		CLEAR_FPU_OWNER();
+		regs->cp0_status &= ~ST0_CU1;
+	}
+	if (current->used_math) {
+		/* Undo possible contamination of thread state */
+		err |= restore_thread_fp_context(sc);
 	}
 
+out:
 	return err;
 }
 
@@ -335,13 +360,55 @@
 	sigset_t sf_mask;
 };
 
-struct rt_sigframe {
+struct rt_sigframe32 {
 	u32 rs_ass[4];			/* argument save space for o32 */
 	u32 rs_code[2];			/* signal trampoline */
-	struct siginfo rs_info;
+	struct siginfo32 rs_info;
 	struct ucontext rs_uc;
 };
 
+static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
+{
+	int err;
+
+	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
+		return -EFAULT;
+
+	/* 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.
+	   This routine must convert siginfo from 64bit to 32bit as well
+	   at the same time.  */
+	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);
+	if (from->si_code < 0)
+		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+	else {
+		switch (from->si_code >> 16) {
+		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_pid, &to->si_pid);
+			err |= __put_user(from->si_uid, &to->si_uid);
+			break;
+		case __SI_FAULT >> 16:
+			err |= __put_user((long)from->si_addr, &to->si_addr);
+			break;
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_band, &to->si_band);
+			err |= __put_user(from->si_fd, &to->si_fd);
+			break;
+		/* case __SI_RT: This is not generated by the kernel as of now.  */
+		}
+	}
+	return err;
+}
+
 asmlinkage void sys32_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
 	struct sigframe *frame;
@@ -369,7 +436,7 @@
 		syscall_trace();
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
-		"j\to32_ret_from_sys_call"
+		"j\tret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
@@ -380,11 +447,11 @@
 
 asmlinkage void sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe32 *frame;
 	sigset_t set;
 	stack_t st;
 
-	frame = (struct rt_sigframe *) regs.regs[29];
+	frame = (struct rt_sigframe32 *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
@@ -410,7 +477,7 @@
 	 */
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
-		"j\to32_ret_from_sys_call"
+		"j\tret_from_sys_call"
 		:/* no outputs */
 		:"r" (&regs));
 	/* Unreached */
@@ -422,9 +489,11 @@
 static int inline setup_sigcontext(struct pt_regs *regs,
 				   struct sigcontext *sc)
 {
+	int owned_fp;
 	int err = 0;
 
 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
 #define save_gp_reg(i) {						\
 	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
@@ -445,20 +514,27 @@
 	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 
-	if (current->used_math) {	/* fp is active.  */
-		if (IS_FPU_OWNER()) {
-			lazy_fpu_switch(current, 0);
-			CLEAR_FPU_OWNER();
-			regs->cp0_status &= ~ST0_CU1;
-		}
-		err |= __put_user(1, &sc->sc_ownedfp);
-		err |= store_fp_context(sc);
-		current->used_math = 0;
-	} else {
-		err |= __put_user(0, &sc->sc_ownedfp);
+	owned_fp = IS_FPU_OWNER();
+	err |= __put_user(owned_fp, &sc->sc_ownedfp);
+	err |= __put_user(current->used_math, &sc->sc_used_math);
+
+	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);
+		goto out;
 	}
-	err |= __put_user(regs->cp0_status, &sc->sc_status);
 
+	/*
+	 * Someone else has FPU.
+	 * Copy Thread context into signal context
+	 */
+	err |= save_thread_fp_context(sc);
+
+out:
 	return err;
 }
 
@@ -473,6 +549,13 @@
 	/* 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;
@@ -547,7 +630,7 @@
 				  struct pt_regs *regs, int signr,
 				  sigset_t *set, siginfo_t *info)
 {
-	struct rt_sigframe *frame;
+	struct rt_sigframe32 *frame;
 	int err = 0;
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -572,8 +655,8 @@
 		flush_cache_sigtramp((unsigned long) frame->rs_code);
 	}
 
-	/* Create siginfo.  */
-	err |= __copy_to_user(&frame->rs_info, info, sizeof(*info));
+	/* Convert (siginfo_t -> siginfo_t32) and copy to user. */
+	err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -598,7 +681,7 @@
 	 *   a2 = pointer to ucontext
 	 *
 	 * $25 and c0_epc point to the signal handler, $29 points to
-	 * the struct rt_sigframe.
+	 * the struct rt_sigframe32.
 	 */
 	regs->regs[ 4] = signr;
 	regs->regs[ 5] = (unsigned long) &frame->rs_info;
@@ -784,7 +867,7 @@
 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set,
 						old_sigset_t *oset);
 
-asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, 
+asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set,
 				 old_sigset_t32 *oset)
 {
 	old_sigset_t s;
@@ -878,7 +961,7 @@
 
 	if (set && get_sigset(&new_set, set))
 		return -EFAULT;
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
 				 oset ? &old_set : NULL, sigsetsize);
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/smp.c linux-2.4.20-pre7/arch/mips64/kernel/smp.c
--- linux-2.4.20-pre6/arch/mips64/kernel/smp.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/smp.c	Thu Sep 12 20:01:40 2002
@@ -1,13 +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.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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) 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/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -17,7 +29,6 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
-#include <linux/cache.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -26,14 +37,13 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/mmu_context.h>
-#include <asm/irq.h>
+#include <asm/smp.h>
 
 /* 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];
-void (*volatile smp_cpu0_finalize)(void);
 
 // static atomic_t cpus_booted = ATOMIC_INIT(0);
 atomic_t cpus_booted = ATOMIC_INIT(0);
@@ -44,8 +54,36 @@
 int __cpu_logical_map[NR_CPUS];
 cycles_t cacheflush_time;
 
-// static void smp_tune_scheduling (void)
-void smp_tune_scheduling (void)
+/* These are defined by the board-specific code. */
+
+/*
+ * 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
+ * values, and kick the cpu into smp_bootstrap();
+ */
+void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+
+/*
+ *  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);
+
+/*
+ * 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);
+
+void prom_smp_finish(void);
+
+static void smp_tune_scheduling(void)
 {
 }
 
@@ -100,12 +138,6 @@
 	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
 }
 
-/* Not really SMP stuff ... */
-int setup_profiling_timer(unsigned int multiplier)
-{
-	return 0;
-}
-
 static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
 
 struct call_data_struct *call_data;
@@ -121,8 +153,7 @@
  * Does not return until remote CPUs are nearly ready to execute <func>
  * or are or have executed.
  */
-
-int smp_call_function (void (*func) (void *info), void *info, int retry, 
+int smp_call_function (void (*func) (void *info), void *info, int retry,
 								int wait)
 {
 	struct call_data_struct data;
@@ -188,21 +219,32 @@
 
 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();
+	/*
+	 * Remove this CPU:
+	 */
+	clear_bit(smp_processor_id(), &cpu_online_map);
+	/* May need to service _machine_restart IPI */
+	__sti();
+	/* XXXKW wait if available? */
+	for (;;);
 }
 
 void smp_send_stop(void)
 {
 	smp_call_function(stop_this_cpu, NULL, 1, 0);
+	/*
+	 * Fix me: this prevents future IPIs, for example that would
+	 * cause a restart to happen on CPU0.
+	 */
 	smp_num_cpus = 1;
 }
 
+/* Not really SMP stuff ... */
+int setup_profiling_timer(unsigned int multiplier)
+{
+	return 0;
+}
+
 static void flush_tlb_all_ipi(void *info)
 {
 	local_flush_tlb_all();
@@ -220,11 +262,11 @@
 }
 
 /*
- * The following tlb flush calls are invoked when old translations are 
+ * 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 
+ * 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
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/softfp.S linux-2.4.20-pre7/arch/mips64/kernel/softfp.S
--- linux-2.4.20-pre6/arch/mips64/kernel/softfp.S	Sun Jul  9 22:18:16 2000
+++ linux-2.4.20-pre7/arch/mips64/kernel/softfp.S	Wed Dec 31 16:00:00 1969
@@ -1,666 +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) 1998, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
- *
- * For now it's just a crude hack good enough to run certain fp programs like
- * Mozilla.
- * XXX: Handle MIPS II/III/IV/V enhancements, exceptions, ...
- */
-#include <asm/regdef.h>
-#include <asm/asm.h>
-
-#ifndef __KERNEL__
-#define printk printf
-#endif
-
-#define LOCK_KERNEL
-#define UNLOCK_KERNEL
-
-/*
- * This duplicates definitions from <linux/kernel.h>.
- */
-#define KERN_EMERG      "<0>"   /* system is unusable                   */
-#define KERN_ALERT      "<1>"   /* action must be taken immediately     */
-#define KERN_CRIT       "<2>"   /* critical conditions                  */
-#define KERN_ERR        "<3>"   /* error conditions                     */
-#define KERN_WARNING    "<4>"   /* warning conditions                   */
-#define KERN_NOTICE     "<5>"   /* normal but significant condition     */
-#define KERN_INFO       "<6>"   /* informational                        */
-#define KERN_DEBUG      "<7>"   /* debug-level messages                 */
-
-/*
- * This duplicates definitions from <asm/signal.h>
- */
-#define SIGILL           4      /* Illegal instruction (ANSI).  */
-
-/*
- * Definitions about the instruction format
- */
-#define fd_shift	6
-#define fr_shift	21
-#define fs_shift	11
-#define ft_shift	16
-
-/*
- * NaNs as use by the MIPS architecture
- */
-#define S_QNaN		0x7fbfffff
-#define D_QNaN		0x7ff7ffffffffffff
-#define W_QNaN		0x7fffffff
-#define L_QNaN		0x7fffffffffffffff
-
-/*
- * Checking for NaNs
- */
-#define S_is_QNaN(reg,res)						\
-	sll	res, reg, S_F_size - S_F_bits
-#define D_is_QNaN(reg1,reg2,res)					\
-	sll	res, reg1, (D_F_size - 32) - (D_F_bits - 32);		\
-	or	res, reg2
-
-/*
- * Checking for Denorms
- */
-#define S_is_Denorm(reg,res)						\
-	li	res, 1 << (S_F_bits - 1);				\
-	and	reg, res
-
-/*
- * Some constants that define the properties of single precission numbers.
- */
-#define S_M_prec	24
-#define S_E_max		127
-#define S_E_min		-126
-#define S_E_bias	127
-#define S_E_bits	8
-#define S_F_bits	23
-#define S_F_size	32
-
-/* Set temp0, if exponent of reg is S_E_max + 1.  */
-#define S_is_E_max(reg,temp0,temp1)					\
-	li	temp0, (S_E_max + 1 + S_E_bias) << S_F_bits;		\
-	and	temp1, temp0, reg;					\
-	seq	temp0, temp1			/* temp0 != 0 if NaN */
-
-/* Clear temp0, if exponent of reg is S_E_min - 1.  */
-#define S_is_E_min(reg,temp0)						\
-	li	temp0, (S_E_min - 1 + S_E_bias) << S_F_bits;		\
-	and	temp0, reg	/* temp0 == 0 if denorm or zero */
-
-/* Set temp0 if reg is a NaN assuming S_is_E_max is true  */
-#define S_get_F(reg,temp0)						\
-	li	temp0, (1 << S_F_bits) - 1;				\
-	and	temp0, reg			/* temp0 != 0 if NaN */
-
-/* Set res if fraction of reg is != 0.  */
-#define S_is_Inf(reg,res)						\
-	li	res, (1 << S_F_bits) - 1;				\
-	and	res, reg			/* temp0 == 0 if Inf */
-
-
-/*
- * Some constants that define the properties of double precission numbers.
- */
-#define D_M_prec	53
-#define D_E_max		1023
-#define D_E_min		-1022
-#define D_E_bias	1023
-#define D_E_bits	8
-#define D_F_bits	52
-#define D_F_size	64
-
-/* Set temp0, if exponent of reg1/reg2 is D_E_max.  */
-#define D_is_E_max(reg1,reg2,temp0,temp1)				\
-	li	temp0, (D_E_max + 1 + D_E_bias) << (D_F_bits - 32);	\
-	and	temp1, temp0, reg1;					\
-	seq	temp0, temp1			/* temp0 != 0 if NaN */
-
-/* Clear temp0, if exponent of reg is D_E_min.  */
-#define D_is_E_min(reg1,reg2,res)					\
-	li	res, (D_E_min + 1 + D_E_bias) << (D_F_bits - 32);	\
-	and	res, reg1	/* temp0 == 0 if NaN or zero */
-
-/* Set res if reg is a NaN assuming S_is_E_max is true  */
-#define D_get_F(reg1,reg2,res)						\
-	li	res, (1 << (D_F_bits - 32)) - 1;			\
-	and	res, reg1			/* temp0 != 0 if NaN */
-
-/* Set temp0 if reg1/reg2 is a NaN  */
-#define D_is_NAN(reg1,reg2,temp0,temp1)					\
-	li	temp0, (1 << (D_F_bits - 32) - 1;			\
-	and	temp0, reg1;						\
-	or	temp0, reg2;						\
-	sne	temp0, zero, temp0		/* temp0 != 0 if NaN */
-
-/* Set res if fraction of reg1/reg2 is != 0.  */
-#define D_is_Inf(reg1,reg2,res)						\
-	li	res, (1 << (D_F_bits - 32)) - 1;			\
-	and	res, reg1;						\
-	or	res, reg2			/* temp0 == 0 if Inf */
-
-/* Complain about yet unhandled instruction.  */
-#define BITCH(insn)							\
-insn:	LOCK_KERNEL;							\
-	la	a1, 8f;							\
-	TEXT(#insn);							\
-	la	a0, nosim;						\
-	jal	printk;							\
-	UNLOCK_KERNEL;							\
-	j	done
-
-	.data
-nosim: .asciz	KERN_DEBUG "Don't know how to simulate %s instruction\n"
-	.previous
-
-/*
- * When we come here, we've saved some of the integer registers and
- * reenabled interrupts.
- */
-LEAF(simfp)
-	.set	noreorder
-	.cpload	$25
-	.set	reorder
-
-	dsubu	sp, 16
-	.cprestore 20
-	sd	ra, 0(sp)
-
-	/* For now we assume that we get the opcode to simulate passed in as
-	   an argument.  */
-	move	ta0, a0
-
-	/*
-	 * First table lookup using insn[5:0]
-	 */
-	la	ta1, lowtab
-	andi	ta2, ta0, 0x3f
-	sll	ta2, ta2, 3
-	daddu	ta1, ta2
-	ld	ta1, (ta1)
-	jr	ta1
-	END(simfp)
-
-/*
- * We only decode the lower 3 of the 5 bit in the fmt field.  That way we
- * can keep the jump table significantly shorter.
- */
-#define FMT_switch(insn,opc,temp0,temp1)				\
-insn:	srl	temp0, opc, 18;						\
-	andi	temp0, 0x1c;						\
-	la	temp1, insn##.tab;					\
-	daddu	temp0, temp1;						\
-	ld	temp0, (temp0);						\
-	jr	temp0;							\
-									\
-	.data;								\
-insn##.tab:								\
-	.dword	insn##.s, insn##.d, unimp, unimp;			\
-	.dword	insn##.w, insn##.l, unimp, unimp;			\
-	.previous
-
-	BITCH(add)
-	BITCH(sub)
-	BITCH(mul)
-	BITCH(div)
-	BITCH(sqrt)
-	BITCH(abs)
-	BITCH(mov)
-	BITCH(neg)
-	BITCH(round.l)
-	BITCH(trunc.l)
-	BITCH(ceil.l)
-	BITCH(floor.l)
-	BITCH(round.w)
-	BITCH(trunc.w)
-	BITCH(ceil.w)
-	BITCH(floor.w)
-	BITCH(cvt.s)
-	BITCH(cvt.d)
-
-/* ------------------------------------------------------------------------ */
-
-FMT_switch(cvt.w,ta0,ta1,ta2)
-
-/* Convert a single fp to a fixed point integer.  */
-cvt.w.s:
-	srl	ta1, ta0, fs_shift	# Get source register
-	andi	ta1, 31
-	jal	s_get_fpreg
-
-	S_is_E_max(ta1,ta2,ta3)
-	beqz	ta2, 3f
-	/* Might be a NaN or Inf.  */
-	S_get_F(ta1,ta2)
-	beqz	ta2, 2f
-
-	/* It's a NaN.  IEEE says undefined.  */
-	/* Is it a QNaN?  Then the result is a QNaN as well.  */
-	S_is_QNaN(ta1,ta2)
-	bltz	ta2, 1f
-
-	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
-	   For now we don't signal and supply a QNaN for result.  */
-
-1:	li	ta2, W_QNaN
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	S_is_Inf(ta1,ta2)
-	bnez	ta2, 2f
-
-	/* It's +/- Inf.  Set register to +/- max. integer.  */
-	/* XXX Send invalid operation exception instead, if enabled.  */
-	srl	ta1, ta1, 31		# Extract sign bit
-	li	ta2, 0x7fffffff
-	addu	ta2, ta1
-
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-3:	
-
-	/* But then it might be a denorm or zero?  */
-	S_is_E_min(ta1,ta2)
-	bnez	ta2, 2f
-
-	/* Ok, it's a denorm or zero.  */
-	S_get_F(ta1,ta2)
-	beqz	ta2, 1f
-
-	/* It's a denorm.  */
-	/* XXX Should be signaling inexact exception, if enabled.  */
-	/* Fall through.  */
-1:
-	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
-	move	ta2, zero
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	/* XXX Ok, it's a normal number.  We don't handle that case yet.
-	   If we have fp hardware this case is unreached.  Add this for
-	   full fp simulation.  */
-
-	/* Done, return.  */
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-/* Convert a double fp to a fixed point integer.  */
-cvt.w.d:
-	srl	ta1, ta0, fs_shift	# Get source register
-	andi	ta1, 31
-	jal	d_get_fpreg
-
-	D_is_E_max(ta1,ta2,ta3,t0)
-	beqz	ta3, 3f
-
-	/* Might be a NaN or Inf.  */
-	D_get_F(ta1,ta2,ta3)
-	or	ta3, ta2
-	beqz	ta3, 2f
-
-	/* It's a NaN.  IEEE says undefined.  */
-	/* Is it a QNaN?  Then the result is a QNaN as well.  */
-	D_is_QNaN(ta1,ta2,ta3)
-	bltz	ta3, 1f
-
-	/* XXX Ok, it's a SNaN.  Signal invalid exception, if enabled.
-	   For now we don't signal and supply a QNaN for result.  */
-
-1:	li	ta2, W_QNaN
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	D_is_Inf(ta1,ta2,ta3)
-	bnez	ta3, 2f
-
-	/* It's +/- Inf.  Set register to +/- max. integer.  */
-	/* XXX Send invalid operation exception instead, if enabled.  */
-	srl	ta1, ta1, 31		# Extract sign bit
-	li	ta2, 0x7fffffff
-	addu	ta2, ta1
-
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-3:	
-
-	/* But then it might be a denorm or zero?  */
-	D_is_E_min(ta1,ta2,ta3)
-	bnez	ta3, 2f
-
-	/* Ok, it's a denorm or zero.  */
-	D_get_F(ta1,ta2,ta3)
-	or	ta3, ta2
-	beqz	ta3, 1f
-
-	/* It's a denorm.  */
-	/* XXX Should be signaling inexact exception, if enabled.  */
-	/* Fall through.  */
-1:
-	/* Yes, it is a denorm or zero.  Supply a zero as result.  */
-	move	ta2, zero
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-	j	done
-2:
-
-	/* XXX Ok, it's a normal number.  We don't handle that case yet.
-	   If we have fp hardware this case is only reached if the value
-	   of the source register exceeds the range which is representable
-	   in a single precission register.  For now we kludge by returning
-	   +/- maxint and don't signal overflow. */
-
-	srl	ta1, ta1, 31		# Extract sign bit
-	li	ta2, 0x7fffffff
-	addu	ta2, ta1
-
-	srl	ta1, ta0, fd_shift	# Put result register
-	andi	ta1, 31
-	jal	s_put_fpreg
-
-	/* Done, return.  */
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-cvt.w.w = unimp				# undefined result
-cvt.w.l = unimp				# undefined result
-
-/* MIPS III extension, no need to handle for 32bit OS.  */
-cvt.l = unimp
-
-/* ------------------------------------------------------------------------ */
-
-	BITCH(c.f)
-	BITCH(c.un)
-	BITCH(c.eq)
-	BITCH(c.ueq)
-	BITCH(c.olt)
-	BITCH(c.ult)
-	BITCH(c.ole)
-	BITCH(c.ule)
-	BITCH(c.sf)
-	BITCH(c.ngle)
-	BITCH(c.seq)
-	BITCH(c.ngl)
-	BITCH(c.lt)
-	BITCH(c.nge)
-	BITCH(c.le)
-	BITCH(c.ngt)
-
-/* Get the single precission register which's number is in ta1.  */
-s_get_fpreg:
-	.set	noat
-	sll	ta1, 3
-	la	AT, 1f
-	daddu	AT, ta1
-	jr	AT
-	.set	at
-
-1:	mfc1	ta1, $0
-	jr	ra
-	mfc1	ta1, $1
-	jr	ra
-	mfc1	ta1, $2
-	jr	ra
-	mfc1	ta1, $3
-	jr	ra
-	mfc1	ta1, $4
-	jr	ra
-	mfc1	ta1, $5
-	jr	ra
-	mfc1	ta1, $6
-	jr	ra
-	mfc1	ta1, $7
-	jr	ra
-	mfc1	ta1, $8
-	jr	ra
-	mfc1	ta1, $9
-	jr	ra
-	mfc1	ta1, $10
-	jr	ra
-	mfc1	ta1, $11
-	jr	ra
-	mfc1	ta1, $12
-	jr	ra
-	mfc1	ta1, $13
-	jr	ra
-	mfc1	ta1, $14
-	jr	ra
-	mfc1	ta1, $15
-	jr	ra
-	mfc1	ta1, $16
-	jr	ra
-	mfc1	ta1, $17
-	jr	ra
-	mfc1	ta1, $18
-	jr	ra
-	mfc1	ta1, $19
-	jr	ra
-	mfc1	ta1, $20
-	jr	ra
-	mfc1	ta1, $21
-	jr	ra
-	mfc1	ta1, $22
-	jr	ra
-	mfc1	ta1, $23
-	jr	ra
-	mfc1	ta1, $24
-	jr	ra
-	mfc1	ta1, $25
-	jr	ra
-	mfc1	ta1, $26
-	jr	ra
-	mfc1	ta1, $27
-	jr	ra
-	mfc1	ta1, $28
-	jr	ra
-	mfc1	ta1, $29
-	jr	ra
-	mfc1	ta1, $30
-	jr	ra
-	mfc1	ta1, $31
-	jr	ra
-
-/*
- * Put the value in ta2 into the single precission register which's number
- * is in ta1.
- */
-s_put_fpreg:
-	.set	noat
-	sll	ta1, 3
-	la	AT, 1f
-	daddu	AT, ta1
-	jr	AT
-	.set	at
-	
-1:	mtc1	ta2, $0
-	jr	ra
-	mtc1	ta2, $1
-	jr	ra
-	mtc1	ta2, $2
-	jr	ra
-	mtc1	ta2, $3
-	jr	ra
-	mtc1	ta2, $4
-	jr	ra
-	mtc1	ta2, $5
-	jr	ra
-	mtc1	ta2, $6
-	jr	ra
-	mtc1	ta2, $7
-	jr	ra
-	mtc1	ta2, $8
-	jr	ra
-	mtc1	ta2, $9
-	jr	ra
-	mtc1	ta2, $10
-	jr	ra
-	mtc1	ta2, $11
-	jr	ra
-	mtc1	ta2, $12
-	jr	ra
-	mtc1	ta2, $13
-	jr	ra
-	mtc1	ta2, $14
-	jr	ra
-	mtc1	ta2, $15
-	jr	ra
-	mtc1	ta2, $16
-	jr	ra
-	mtc1	ta2, $17
-	jr	ra
-	mtc1	ta2, $18
-	jr	ra
-	mtc1	ta2, $19
-	jr	ra
-	mtc1	ta2, $20
-	jr	ra
-	mtc1	ta2, $21
-	jr	ra
-	mtc1	ta2, $22
-	jr	ra
-	mtc1	ta2, $23
-	jr	ra
-	mtc1	ta2, $24
-	jr	ra
-	mtc1	ta2, $25
-	jr	ra
-	mtc1	ta2, $26
-	jr	ra
-	mtc1	ta2, $27
-	jr	ra
-	mtc1	ta2, $28
-	jr	ra
-	mtc1	ta2, $29
-	jr	ra
-	mtc1	ta2, $30
-	jr	ra
-	mtc1	ta2, $31
-	jr	ra
-
-/* Get the double precission register which's number is in ta1 into ta1/ta2.  */
-d_get_fpreg:
-	.set	noat
-	sll	AT, ta1, 1
-	sll	ta1, 2
-	daddu	ta1, AT
-	la	AT, 1f
-	daddu	AT, ta1
-	jr	AT
-	.set	at
-
-1:	mfc1	ta1, $0
-	mfc1	ta2, $1
-	jr	ra
-	mfc1	ta1, $2
-	mfc1	ta2, $3
-	jr	ra
-	mfc1	ta1, $4
-	mfc1	ta2, $5
-	jr	ra
-	mfc1	ta1, $6
-	mfc1	ta2, $7
-	jr	ra
-	mfc1	ta1, $8
-	mfc1	ta2, $9
-	jr	ra
-	mfc1	ta1, $10
-	mfc1	ta2, $11
-	jr	ra
-	mfc1	ta1, $12
-	mfc1	ta2, $13
-	jr	ra
-	mfc1	ta1, $14
-	mfc1	ta2, $15
-	jr	ra
-	mfc1	ta1, $16
-	mfc1	ta2, $17
-	jr	ra
-	mfc1	ta1, $18
-	mfc1	ta2, $19
-	jr	ra
-	mfc1	ta1, $20
-	mfc1	ta2, $21
-	jr	ra
-	mfc1	ta1, $22
-	mfc1	ta2, $23
-	jr	ra
-	mfc1	ta1, $24
-	mfc1	ta2, $25
-	jr	ra
-	mfc1	ta1, $26
-	mfc1	ta2, $27
-	jr	ra
-	mfc1	ta1, $28
-	mfc1	ta2, $29
-	jr	ra
-	mfc1	ta1, $30
-	mfc1	ta2, $31
-	jr	ra
-
-/*
- * Send an invalid operation exception.
- */
-invalid:
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-/*
- * Done, just skip over the current instruction
- */
-done:
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-unimp:
-	/* We've run into an yet unknown instruction.  This happens either
-	   on new, yet unsupported CPU types or when the faulting instruction
-	   is being executed for cache but has been overwritten in memory.  */
-	LOCK_KERNEL
-	move	a1, ta0
-	PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ")
-	PRINT("please mail to ralf@gnu.org.\n")
-	UNLOCK_KERNEL
-
-	li	a0, SIGILL			# Die, sucker ...
-	move	a1, $28
-	jal	force_sig
-
-	ld	ra, 0(sp)
-	daddu	sp, 16
-	jr	ra
-
-/*
- * Jump table for the lowest 6 bits of a cp1 instruction.
- */
-	.data
-lowtab:	.dword	add,   sub,   mul,   div,   sqrt,  abs,   mov,   neg
-	.dword	round.l,trunc.l,ceil.l,floor.l,round.w,trunc.w,ceil.w,floor.w
-	.dword	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
-	.dword	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
-	.dword	cvt.s, cvt.d, unimp, unimp, cvt.w, cvt.l, unimp, unimp
-	.dword	unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp
-	.dword	c.f,   c.un,  c.eq,  c.ueq, c.olt, c.ult, c.ole, c.ule
-	.dword	c.sf,  c.ngle,c.seq, c.ngl, c.lt,  c.nge, c.le, c.ngt
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/syscall.c linux-2.4.20-pre7/arch/mips64/kernel/syscall.c
--- linux-2.4.20-pre6/arch/mips64/kernel/syscall.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/syscall.c	Thu Sep 12 20:01:40 2002
@@ -261,7 +261,7 @@
 	}
 
 	case MSGSND:
-		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+		return sys_msgsnd (first, (struct msgbuf *) ptr,
 				   second, third);
 	case MSGRCV:
 		switch (version) {
@@ -269,9 +269,9 @@
 			struct ipc_kludge tmp;
 			if (!ptr)
 				return -EINVAL;
-			
+
 			if (copy_from_user(&tmp,
-					   (struct ipc_kludge *) ptr, 
+					   (struct ipc_kludge *) ptr,
 					   sizeof (tmp)))
 				return -EFAULT;
 			return sys_msgrcv (first, tmp.msgp, second,
@@ -301,7 +301,7 @@
 				return -EINVAL;
 			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 		}
-	case SHMDT: 
+	case SHMDT:
 		return sys_shmdt ((char *)ptr);
 	case SHMGET:
 		return sys_shmget (first, second, third);
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/time.c linux-2.4.20-pre7/arch/mips64/kernel/time.c
--- linux-2.4.20-pre6/arch/mips64/kernel/time.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/time.c	Thu Sep 12 20:01:40 2002
@@ -2,8 +2,8 @@
  * 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. 
+ * 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
@@ -289,9 +289,9 @@
 
 /*
  * local_timer_interrupt() does profiling and process accounting
- * on a per-CPU basis.  
+ * on a per-CPU basis.
  *
- * In UP mode, it is invoked from the (global) timer_interrupt.  
+ * 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
@@ -368,7 +368,7 @@
 		if (rtc_set_time(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
-			last_rtc_update = xtime.tv_sec - 600; 
+			last_rtc_update = xtime.tv_sec - 600;
 			/* do it again in 60 s */
 		}
 	}
@@ -384,9 +384,9 @@
 	}
 
 #if !defined(CONFIG_SMP)
-	/* 
+	/*
 	 * In UP mode, we call local_timer_interrupt() to do profiling
-	 * and process accouting.  
+	 * and process accouting.
 	 *
 	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
 	 * low-level local timer interrupt handler.
@@ -396,7 +396,7 @@
 #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.
@@ -418,7 +418,7 @@
 
 	/* we keep interrupt disabled all the time */
 	timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -434,7 +434,7 @@
 
 	/* we keep interrupt disabled all the time */
 	local_timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -444,19 +444,19 @@
 /*
  * time_init() - it does the following things.
  *
- * 1) board_time_init() - 
- * 	a) (optional) set up RTC routines, 
+ * 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() - 
+ * 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;
@@ -496,10 +496,12 @@
 		/* 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) {
+		u32 count;
+
 		cycles_per_jiffy = mips_counter_frequency / HZ;
 
 		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */
@@ -507,16 +509,24 @@
 		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
 		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
 		sll32_usecs_per_cycle *= 10;
+
+		/*
+		 * For those using cpu counter as timer,  this sets up the
+		 * first interrupt
+		 */
+		count = read_32bit_cp0_register(CP0_COUNT);
+		write_32bit_cp0_register (CP0_COMPARE,
+					  count + cycles_per_jiffy);
 	}
 
-	/* 
+	/*
 	 * Call board specific timer interrupt setup.
 	 *
-	 * this pointer must be setup in machine setup routine. 
+	 * 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 
+	 * 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.
 	 */
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/traps.c linux-2.4.20-pre7/arch/mips64/kernel/traps.c
--- linux-2.4.20-pre6/arch/mips64/kernel/traps.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/traps.c	Thu Sep 12 20:01:40 2002
@@ -31,6 +31,7 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/cachectl.h>
+#include <asm/types.h>
 
 extern asmlinkage void __xtlb_mod(void);
 extern asmlinkage void __xtlb_tlbl(void);
@@ -50,7 +51,9 @@
 extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
-extern int fpu_emulator_cop1Handler(struct pt_regs *);
+extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
+	struct mips_fpu_soft_struct *ctx);
+
 void fpu_emulator_init_fpu(void);
 
 char watch_available = 0;
@@ -66,61 +69,94 @@
  */
 #define MODULE_RANGE (8*1024*1024)
 
+#define OPCODE 0xfc000000
+
+/*
+ * If the address is either in the .text section of the
+ * kernel, or in the vmalloc'ed module regions, it *may*
+ * be the address of a calling routine
+ */
+
+#ifdef CONFIG_MODULES
+
+extern struct module *module_list;
+extern struct module kernel_module;
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+	int retval = 0;
+	struct module *mod;
+
+	if (addr >= (long) &_stext && addr <= (long) &_etext)
+		return 1;
+
+	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;
+		}
+	}
+
+	return retval;
+}
+
+#else
+
+static inline int kernel_text_address(long addr)
+{
+	extern char _stext, _etext;
+
+	return (addr >= (long) &_stext && addr <= (long) &_etext);
+}
+
+#endif
+
 /*
  * This routine abuses get_user()/put_user() to reference pointers
  * with at least a bit of error checking ...
  */
-void show_stack(unsigned long *sp)
+void show_stack(long *sp)
 {
 	int i;
-	unsigned long *stack;
-
-	stack = sp;
-	i = 0;
+	long stackdata;
 
 	printk("Stack:");
-	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
-		unsigned long stackdata;
-
-		if (__get_user(stackdata, stack++)) {
-			printk(" (Bad stack address)");
+	i = 0;
+	while ((long) sp & (PAGE_SIZE - 1)) {
+		if (i && ((i % 4) == 0))
+			printk("\n      ");
+		if (i > 40) {
+			printk(" ...");
 			break;
 		}
 
-		printk(" %016lx", stackdata);
-
-		if (++i > 40) {
-			printk(" ...");
+		if (__get_user(stackdata, sp++)) {
+			printk(" (Bad stack address)");
 			break;
 		}
 
-		if (i % 4 == 0)
-			printk("\n      ");
+		printk(" %016lx", stackdata);
+		i++;
 	}
+	printk("\n");
 }
 
-void show_trace(unsigned long *sp)
+void show_trace(long *sp)
 {
 	int i;
-	unsigned long *stack;
-	unsigned long kernel_start, kernel_end;
-	unsigned long module_start, module_end;
-	extern char _stext, _etext;
+	long addr;
 
-	stack = sp;
+	printk("Call Trace:");
 	i = 0;
+	while ((long) sp & (PAGE_SIZE - 1)) {
 
-	kernel_start = (unsigned long) &_stext;
-	kernel_end = (unsigned long) &_etext;
-	module_start = VMALLOC_START;
-	module_end = module_start + MODULE_RANGE;
-
-	printk("\nCall Trace:");
-
-	while ((unsigned long) stack & (PAGE_SIZE - 1)) {
-		unsigned long addr;
-
-		if (__get_user(addr, stack++)) {
+		if (__get_user(addr, sp++)) {
+			if (i && ((i % 3) == 0))
+				printk("\n           ");
 			printk(" (Bad stack address)\n");
 			break;
 		}
@@ -134,25 +170,24 @@
 		 * out the call path that was taken.
 		 */
 
-		if ((addr >= kernel_start && addr < kernel_end) ||
-		    (addr >= module_start && addr < module_end)) { 
-
-			/* Since our kernel is still at KSEG0,
-			 * truncate the address so that ksymoops
-			 * understands it.
-			 */
-			printk(" [<%08x>]", (unsigned int) addr);
-			if (++i > 40) {
+		if (kernel_text_address(addr)) {
+			if (i && ((i % 3) == 0))
+				printk("\n           ");
+			if (i > 40) {
 				printk(" ...");
 				break;
 			}
+
+			printk(" [<%016lx>]", addr);
+			i++;
 		}
 	}
+	printk("\n");
 }
 
 void show_trace_task(struct task_struct *tsk)
 {
-	show_trace((unsigned long *)tsk->thread.reg29);
+	show_trace((long *)tsk->thread.reg29);
 }
 
 
@@ -216,31 +251,38 @@
 	printk("Cause   : %08x\n", (unsigned int) regs->cp0_cause);
 }
 
-static spinlock_t die_lock;
-
-void die(const char * str, struct pt_regs * regs)
+void show_registers(struct pt_regs *regs)
 {
-	if (user_mode(regs))	/* Just return if in user mode.  */
-		return;
-
-	console_verbose();
-	spin_lock_irq(&die_lock);
-	printk("%s\n", str);
 	show_regs(regs);
-	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+	printk("Process %s (pid: %d, stackpage=%016lx)\n",
 		current->comm, current->pid, (unsigned long) current);
-	show_stack((unsigned long *) regs->regs[29]);
-	show_trace((unsigned long *) regs->regs[29]);
+	show_stack((long *) regs->regs[29]);
+	show_trace((long *) 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 * file,
+	   const char * func, unsigned long line)
+{
+	console_verbose();
+	spin_lock_irq(&die_lock);
+	printk("%s", str);
+	if (file && func)
+		printk(" in %s:%s, line %ld", file, func, line);
+	printk(":\n");
+	show_registers(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char * str, struct pt_regs * regs)
+void __die_if_kernel(const char * str, struct pt_regs * regs,
+		     const char * file, const char * func, unsigned long line)
 {
 	if (!user_mode(regs))
-		die(str, regs);
+		__die(str, regs, file, func, line);
 }
 
 extern const struct exception_table_entry __start___dbe_table[];
@@ -353,11 +395,18 @@
 	force_sig(SIGBUS, current);
 }
 
-void do_ov(struct pt_regs *regs)
+asmlinkage void do_ov(struct pt_regs *regs)
 {
+	siginfo_t info;
+
 	if (compute_return_epc(regs))
 		return;
-	force_sig(SIGFPE, current);
+
+	info.si_code = FPE_INTOVF;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->cp0_epc;
+	force_sig_info(SIGFPE, &info, current);
 }
 
 /*
@@ -381,10 +430,11 @@
 		save_fp(current);
 
 		/* Run the emulator */
-		sig = fpu_emulator_cop1Handler(regs);
+		sig = fpu_emulator_cop1Handler (0, regs,
+			&current->thread.fpu.soft);
 
-		/* 
-		 * We can't allow the emulated instruction to leave any of 
+		/*
+		 * 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;
@@ -395,8 +445,8 @@
 		/* If something went wrong, signal */
 		if (sig)
 		{
-			/* 
-			 * Return EPC is not calculated in the FPU emulator, 
+			/*
+			 * Return EPC is not calculated in the FPU emulator,
 			 * if a signal is being send. So we calculate it here.
 			 */
 			compute_return_epc(regs);
@@ -411,16 +461,26 @@
 	force_sig(SIGFPE, current);
 }
 
-void do_bp(struct pt_regs *regs)
+static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode)
+{
+	unsigned long *epc;
+
+	epc = (unsigned long *) regs->cp0_epc +
+	      ((regs->cp0_cause & CAUSEF_BD) != 0);
+	if (!get_user(opcode, epc))
+		return 0;
+
+	force_sig(SIGSEGV, current);
+	return 1;
+}
+
+asmlinkage void do_bp(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
-	unsigned int *epc;
 	siginfo_t info;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
@@ -450,37 +510,30 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-
-	force_sig(SIGTRAP, current);
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
-void do_tr(struct pt_regs *regs)
+asmlinkage void do_tr(struct pt_regs *regs)
 {
-	unsigned int opcode, bcode;
-	unsigned int *epc;
+	unsigned int opcode, tcode = 0;
 	siginfo_t info;
 
-	epc = (unsigned int *) regs->cp0_epc +
-	      ((regs->cp0_cause & CAUSEF_BD) != 0);
-	if (get_user(opcode, epc))
-		goto sigsegv;
+	if (get_insn_opcode(regs, &opcode))
+		return;
 
-	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+        /* Immediate versions don't provide a code.  */
+	if (!(opcode & OPCODE))
+		tcode = ((opcode >> 6) & ((1 << 20) - 1));
 
 	/*
-	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
-	 * insns, even for break codes that indicate arithmetic failures.
-	 * Wiered ...)
+	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
+	 * insns, even for trap codes that indicate arithmetic failures.
+	 * Weird ...)
 	 * But should we continue the brokenness???  --macro
 	 */
-	switch (bcode) {
+	switch (tcode) {
 	case 6:
 	case 7:
-		if (bcode == 7)
+		if (tcode == 7)
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -492,23 +545,22 @@
 	default:
 		force_sig(SIGTRAP, current);
 	}
-	return;
-
-sigsegv:
-	force_sig(SIGSEGV, current);
 }
 
-void do_ri(struct pt_regs *regs)
+asmlinkage void do_ri(struct pt_regs *regs)
 {
+	die_if_kernel("Reserved instruction in kernel code", regs);
+
 	if (compute_return_epc(regs))
 		return;
 
 	force_sig(SIGILL, current);
 }
 
-void do_cpu(struct pt_regs *regs)
+asmlinkage void do_cpu(struct pt_regs *regs)
 {
-	u32 cpid;
+	unsigned int cpid;
+	void fpu_emulator_init_fpu(void);
 	int sig;
 
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
@@ -544,15 +596,17 @@
 	return;
 
 fp_emul:
-	if (!current->used_math) {
-		fpu_emulator_init_fpu();
-		current->used_math = 1;
+	if (last_task_used_math != current) {
+		if (!current->used_math) {
+			fpu_emulator_init_fpu();
+			current->used_math = 1;
+		}
 	}
-	sig = fpu_emulator_cop1Handler(regs);
-	if (sig)
-	{
-		/* 
-		 * Return EPC is not calculated in the FPU emulator, if 
+	sig = fpu_emulator_cop1Handler(0, regs, &current->thread.fpu.soft);
+	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);
@@ -565,12 +619,15 @@
 	force_sig(SIGILL, current);
 }
 
-void do_watch(struct pt_regs *regs)
+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.");
 }
@@ -578,11 +635,17 @@
 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.");
+	dump_tlb_all();
+	/*
+	 * Some chips may have other causes of machine check (e.g. SB1
+	 * graduation timer)
+	 */
+	panic("Caught Machine Check exception - %scaused by multiple "
+	      "matching entries in the TLB.",
+	      (regs->cp0_status & ST0_TS) ? "" : "not ");
 }
 
-void do_reserved(struct pt_regs *regs)
+asmlinkage void do_reserved(struct pt_regs *regs)
 {
 	/*
 	 * Game over - no way to handle this if it ever occurs.  Most probably
@@ -618,18 +681,28 @@
  * to interrupt handlers in the address range from
  * KSEG0 <= x < KSEG0 + 256mb on the Nevada.  Oh well ...
  */
-void set_except_vector(int n, void *addr)
+void *set_except_vector(int n, void *addr)
 {
 	unsigned long handler = (unsigned long) addr;
-	exception_handlers[n] = handler;
+	unsigned long old_handler = exception_handlers[n];
 
+	exception_handlers[n] = handler;
 	if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) {
 		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
 		                                 (0x03ffffff & (handler >> 2));
 		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
 	}
+	return (void *)old_handler;
 }
 
+asmlinkage int (*save_fp_context)(struct sigcontext *sc);
+asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+extern asmlinkage int _save_fp_context(struct sigcontext *sc);
+extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
+
+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();
@@ -653,6 +726,7 @@
 void __init trap_init(void)
 {
 	extern char except_vec0;
+	extern char except_vec1_r4k;
 	extern char except_vec1_r10k;
 	extern char except_vec2_generic;
 	extern char except_vec3_generic, except_vec3_r4000;
@@ -724,10 +798,17 @@
 	case CPU_R4600:
 	case CPU_R5000:
 	case CPU_NEVADA:
+	case CPU_5KC:
+	case CPU_20KC:
+	case CPU_RM7000:
 		/* Debug TLB refill handler.  */
 		memcpy((void *)KSEG0, &except_vec0, 0x80);
-		memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
-
+		if ((mips_cpu.options & MIPS_CPU_4KEX)
+		    && (mips_cpu.options & MIPS_CPU_4KTLB)) {
+			memcpy((void *)KSEG0 + 0x080, &except_vec1_r4k, 0x80);
+		} else {
+			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
+		}
 		if (mips_cpu.options & MIPS_CPU_VCE) {
 			memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000,
 			       0x80);
@@ -764,6 +845,14 @@
 	}
 	flush_icache_range(KSEG0, KSEG0 + 0x200);
 
+	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);
 
diff -urN linux-2.4.20-pre6/arch/mips64/kernel/unaligned.c linux-2.4.20-pre7/arch/mips64/kernel/unaligned.c
--- linux-2.4.20-pre6/arch/mips64/kernel/unaligned.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/kernel/unaligned.c	Thu Sep 12 20:01:40 2002
@@ -41,7 +41,7 @@
  *
  * #include <stdio.h>
  * #include <asm/sysmips.h>
- * 
+ *
  * struct foo {
  *         unsigned char bar[8];
  * };
diff -urN linux-2.4.20-pre6/arch/mips64/ld.script.elf32.S linux-2.4.20-pre7/arch/mips64/ld.script.elf32.S
--- linux-2.4.20-pre6/arch/mips64/ld.script.elf32.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/ld.script.elf32.S	Thu Sep 12 20:01:40 2002
@@ -102,7 +102,7 @@
   }
 
   /* Sections to be discarded */
-  /DISCARD/ : 
+  /DISCARD/ :
   {
         *(.text.exit)
         *(.data.exit)
diff -urN linux-2.4.20-pre6/arch/mips64/ld.script.elf64 linux-2.4.20-pre7/arch/mips64/ld.script.elf64
--- linux-2.4.20-pre6/arch/mips64/ld.script.elf64	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/ld.script.elf64	Thu Sep 12 20:01:40 2002
@@ -8,7 +8,7 @@
   /* This is the value for an Origin kernel, taken from an IRIX kernel.  */
   /* . = 0xc00000000001c000; */
 
-  /* Set the vaddr for the text segment to a value 
+  /* Set the vaddr for the text segment to a value
         >= 0xa800 0000 0001 9000 if no symmon is going to configured
         >= 0xa800 0000 0030 0000 otherwise  */
 
@@ -111,7 +111,7 @@
   }
 
   /* Sections to be discarded */
-  /DISCARD/ : 
+  /DISCARD/ :
   {
         *(.text.exit)
         *(.data.exit)
diff -urN linux-2.4.20-pre6/arch/mips64/lib/csum_partial_copy.c linux-2.4.20-pre7/arch/mips64/lib/csum_partial_copy.c
--- linux-2.4.20-pre6/arch/mips64/lib/csum_partial_copy.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips64/lib/csum_partial_copy.c	Thu Sep 12 20:01:40 2002
@@ -16,7 +16,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy(const char *src, char *dst, 
+unsigned int csum_partial_copy(const char *src, char *dst,
                                int len, unsigned int sum)
 {
 	/*
@@ -44,6 +44,6 @@
 		memset(dst + len - missing, 0, missing);
 		*err_ptr = -EFAULT;
 	}
-		
+
 	return csum_partial(dst, len, sum);
 }
diff -urN linux-2.4.20-pre6/arch/mips64/lib/floppy-std.c linux-2.4.20-pre7/arch/mips64/lib/floppy-std.c
--- linux-2.4.20-pre6/arch/mips64/lib/floppy-std.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/lib/floppy-std.c	Thu Sep 12 20:01:40 2002
@@ -111,8 +111,8 @@
 }
 
 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 -urN linux-2.4.20-pre6/arch/mips64/lib/ide-no.c linux-2.4.20-pre7/arch/mips64/lib/ide-no.c
--- linux-2.4.20-pre6/arch/mips64/lib/ide-no.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips64/lib/ide-no.c	Thu Sep 12 20:01:40 2002
@@ -35,7 +35,7 @@
                               void *dev_id)
 {
 	panic("no_no_ide_request_irq called - shouldn't happen");
-}			
+}
 
 static void no_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -urN linux-2.4.20-pre6/arch/mips64/lib/ide-std.c linux-2.4.20-pre7/arch/mips64/lib/ide-std.c
--- linux-2.4.20-pre6/arch/mips64/lib/ide-std.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/arch/mips64/lib/ide-std.c	Thu Sep 12 20:01:40 2002
@@ -68,7 +68,7 @@
                                 void *dev_id)
 {
 	return request_irq(irq, handler, flags, device, dev_id);
-}			
+}
 
 static void std_ide_free_irq(unsigned int irq, void *dev_id)
 {
diff -urN linux-2.4.20-pre6/arch/mips64/lib/memcpy.S linux-2.4.20-pre7/arch/mips64/lib/memcpy.S
--- linux-2.4.20-pre6/arch/mips64/lib/memcpy.S	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/lib/memcpy.S	Thu Sep 12 20:01:40 2002
@@ -501,7 +501,7 @@
 r_word_align:
 	beqz	t8, r_dword_align
 	 sltiu	t8, a2, 56
-	
+
 	lh	ta0, -2(a1)
 	dsubu	a2, a2, 0x2
 	sh	ta0, -2(a0)
@@ -762,8 +762,18 @@
 	dsubu	a2, AT, ta0			# a2 bytes to go
 	daddu	a0, ta0				# compute start address in a1
 	dsubu	a0, a1
-	j	__bzero
-	 move	a1, zero
+	/*
+	 * Clear len bytes starting at dst.  Can't call __bzero because it
+	 * might modify len.  An inefficient loop for these rare times...
+	 */
+	beqz	a2, 2f
+	 dsubu	a1, a2, 1
+1:	sb	zero, 0(a0)
+	daddu	a0, a0, 1
+	bnez	a1, 1b
+	 dsubu	a1, a1, 1
+2:	jr	ra
+	 nop
 
 s_fixup:
 	jr	ra
diff -urN linux-2.4.20-pre6/arch/mips64/lib/memset.S linux-2.4.20-pre7/arch/mips64/lib/memset.S
--- linux-2.4.20-pre6/arch/mips64/lib/memset.S	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/arch/mips64/lib/memset.S	Thu Sep 12 20:01:40 2002
@@ -52,7 +52,6 @@
 1:
 
 FEXPORT(__bzero)
-	.type	__bzero, @function
 	sltiu	t0, a2, 8			/* very small region? */
 	bnez	t0, small_memset
 	 andi	t0, a0, 7			/* aligned? */
@@ -82,7 +81,7 @@
 	.set	noreorder
 
 memset_partial:
-	la	t1, 2f				/* where to start */
+	PTR_LA	t1, 2f				/* where to start */
 	.set	noat
 	dsrl	AT, t0, 1
 	dsubu	t1, AT
@@ -90,8 +89,12 @@
 	jr	t1
 	 daddu	a0, t0				/* dest ptr */
 
+	.set	push
+	.set	noreorder
+	.set	nomacro
 	F_FILL64(a0, -64, a1, partial_fixup)	/* ... but first do dwds ... */
-2:	andi	a2, 7				/* 0 <= n <= 7 to go */
+2:	.set	pop
+	andi	a2, 7				/* 0 <= n <= 7 to go */
 
 	beqz	a2, 1f
 	 daddu	a0, a2				/* What's left */
diff -urN linux-2.4.20-pre6/arch/mips64/lib/strlen_user.S linux-2.4.20-pre7/arch/mips64/lib/strlen_user.S
--- linux-2.4.20-pre6/arch/mips64/lib/strlen_user.S	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/lib/strlen_user.S	Thu Sep 12 20:01:40 2002
@@ -36,9 +36,5 @@
 	jr	ra
 	END(__strlen_user_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -urN linux-2.4.20-pre6/arch/mips64/lib/strnlen_user.S linux-2.4.20-pre7/arch/mips64/lib/strnlen_user.S
--- linux-2.4.20-pre6/arch/mips64/lib/strnlen_user.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/lib/strnlen_user.S	Thu Sep 12 20:01:40 2002
@@ -24,7 +24,7 @@
  */
 LEAF(__strnlen_user_asm)
 	ld	v0, THREAD_CURDS($28)	# pointer ok?
-	and	v0, ta0
+	and	v0, a0
 	bltz	v0, fault
 
 FEXPORT(__strnlen_user_nocheck_asm)
@@ -38,9 +38,5 @@
 	jr	ra
 	END(__strnlen_user_asm)
 
-	.section	__ex_table,"a"
-	PTR		1b, fault
-	.previous
-
 fault:	move	v0, zero
 	jr	ra
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/Makefile linux-2.4.20-pre7/arch/mips64/math-emu/Makefile
--- linux-2.4.20-pre6/arch/mips64/math-emu/Makefile	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,24 +0,0 @@
-#
-# Makefile for the Linux/MIPS kernel FPU emulation.
-#
-# 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.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
-
-EXTRA_ASFLAGS = -mips2 -mcpu=r4000
-
-O_TARGET:= fpu_emulator.o
-
-obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
-	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
-	   dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
-	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
-	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
-	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
-	   dp_sqrt.o sp_sqrt.o kernel_linkage.o
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/cp1emu.c linux-2.4.20-pre7/arch/mips64/math-emu/cp1emu.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/cp1emu.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/math-emu/cp1emu.c	Wed Dec 31 16:00:00 1969
@@ -1,1812 +0,0 @@
-/*
- * MIPS floating point support
- *
- * 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.
- *
- * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
- * 
- * A complete emulator for MIPS coprocessor 1 instructions.  This is
- * required for #float(switch) or #float(trap), where it catches all
- * COP1 instructions via the "CoProcessor Unusable" exception.  
- *
- * More surprisingly it is also required for #float(ieee), to help out
- * the hardware fpu at the boundaries of the IEEE-754 representation
- * (denormalised values, infinities, underflow, etc).  It is made
- * quite nasty because emulation of some non-COP1 instructions is
- * required, e.g. in branch delay slots.
- * 
- * 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!
- *
- *  Nov 7, 2000
- *  Massive changes to integrate with Linux kernel.
- *
- *  Replace use of kernel data area with use of user stack 
- *  for execution of instructions in branch delay slots.
- *
- *  Replace use of static kernel variables with thread_struct elements.
- *
- * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
- * http://www.algor.co.uk
- *
- * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000  MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/asm.h>
-#include <asm/branch.h>
-#include <asm/bootinfo.h>
-#include <asm/byteorder.h>
-#include <asm/cpu.h>
-#include <asm/inst.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
-#include <asm/fpu_emulator.h>
-
-#include "ieee754.h"
-
-/* Strap kernel emulator for full MIPS IV emulation */
-
-#ifdef __mips
-#undef __mips
-#endif
-#define __mips 4
-
-typedef void *vaddr_t;
-
-/* Function which emulates the instruction in a branch delay slot. */
-
-static int mips_dsemul(struct pt_regs *, mips_instruction, vaddr_t);
-
-/* Function which emulates a floating point instruction. */
-
-static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *,
-	 mips_instruction);
-
-#if __mips >= 4 && __mips != 32
-static int fpux_emu(struct pt_regs *,
-		    struct mips_fpu_soft_struct *, mips_instruction);
-#endif
-
-/* Further private data for which no space exists in mips_fpu_soft_struct */
-
-struct mips_fpu_emulator_private fpuemuprivate;
-
-/* Control registers */
-
-#define FPCREG_RID	0	/* $0  = revision id */
-#define FPCREG_CSR	31	/* $31 = csr */
-
-/* Convert Mips rounding mode (0..3) to IEEE library modes. */
-static const unsigned char ieee_rm[4] = {
-	IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD
-};
-
-#if __mips >= 4
-/* convert condition code register number to csr bit */
-static const unsigned int fpucondbit[8] = {
-	FPU_CSR_COND0,
-	FPU_CSR_COND1,
-	FPU_CSR_COND2,
-	FPU_CSR_COND3,
-	FPU_CSR_COND4,
-	FPU_CSR_COND5,
-	FPU_CSR_COND6,
-	FPU_CSR_COND7
-};
-#endif
-
-
-
-/* 
- * Redundant with logic already in kernel/branch.c,
- * embedded in compute_return_epc.  At some point,
- * a single subroutine should be used across both
- * modules.
- */
-static int isBranchInstr(mips_instruction * i)
-{
-	switch (MIPSInst_OPCODE(*i)) {
-	case spec_op:
-		switch (MIPSInst_FUNC(*i)) {
-		case jalr_op:
-		case jr_op:
-			return 1;
-		}
-		break;
-
-	case bcond_op:
-		switch (MIPSInst_RT(*i)) {
-		case bltz_op:
-		case bgez_op:
-		case bltzl_op:
-		case bgezl_op:
-		case bltzal_op:
-		case bgezal_op:
-		case bltzall_op:
-		case bgezall_op:
-			return 1;
-		}
-		break;
-
-	case j_op:
-	case jal_op:
-	case jalx_op:
-	case beq_op:
-	case bne_op:
-	case blez_op:
-	case bgtz_op:
-	case beql_op:
-	case bnel_op:
-	case blezl_op:
-	case bgtzl_op:
-		return 1;
-
-	case cop0_op:
-	case cop1_op:
-	case cop2_op:
-	case cop1x_op:
-		if (MIPSInst_RS(*i) == bc_op)
-			return 1;
-		break;
-	}
-
-	return 0;
-}
-
-#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);
-	} else {
-		/* Use kernel get_user() macro */
-		*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);
-	} else {
-		/* Use kernel get_user() macro */
-		*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;
-	} else {
-		/* Use kernel get_user() macro */
-		return (int) 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;
-	} else {
-		/* Use kernel get_user() macro */
-		return (int) 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
- * FPRs are desired, there needs to be a flip-flop that can be written
- * to one at that bit position.  In any case, normal MIPS ABI uses
- * only the even FPRs (Status.FR = 0).
- */
-
-#define CP0_STATUS_FR_SUPPORT
-
-/*
- * Emulate the single floating point instruction pointed at by EPC.
- * Two instructions if the instruction is in a branch delay slot.
- */
-
-static int
-cop1Emulate(int xcptno, struct pt_regs *xcp,
-	    struct mips_fpu_soft_struct *ctx)
-{
-	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);
-	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 (xcp->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
-		 * BEFORE we do the cop1 instruction. 
-		 *
-		 * This branch could be a COP1 branch, but in that case we
-		 * would have had a trap for that instruction, and would not
-		 * come through this route.
-		 *
-		 * Linux MIPS branch emulator operates on context, updating the
-		 * cp0_epc.
-		 */
-		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
-
-		if (__compute_return_epc(xcp)) {
-#ifdef CP1DBG
-			printk("failed to emulate branch at %p\n",
-				    REG_TO_VA(xcp->cp0_epc));
-#endif
-			return SIGILL;;
-		}
-		ir = mips_get_word(xcp, emulpc, &err);
-		if (err) {
-			fpuemuprivate.stats.errors++;
-			return SIGBUS;
-		}
-		contpc = REG_TO_VA xcp->cp0_epc;
-	} else {
-		emulpc = REG_TO_VA xcp->cp0_epc;
-		contpc = REG_TO_VA xcp->cp0_epc + 4;
-	}
-
-      emul:
-	fpuemuprivate.stats.emulated++;
-	switch (MIPSInst_OPCODE(ir)) {
-#ifdef CP0_STATUS_FR_SUPPORT
-		/* R4000+ 64-bit fpu registers */
-#ifndef SINGLE_ONLY_FPU
-	case ldc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-			if (!(xcp->cp0_status & ST0_FR))
-				ft &= ~1;
-			ctx->regs[ft] = mips_get_dword(xcp, va, &err);
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-
-	case sdc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			int ft = MIPSInst_RT(ir);
-			if (!(xcp->cp0_status & ST0_FR))
-				ft &= ~1;
-			fpuemuprivate.stats.stores++;
-			if (mips_put_dword(xcp, va, ctx->regs[ft])) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-#endif
-
-	case lwc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			fpureg_t val;
-			int ft = MIPSInst_RT(ir);
-			fpuemuprivate.stats.loads++;
-			val = mips_get_word(xcp, va, &err);
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-			if (xcp->cp0_status & ST0_FR) {
-				/* load whole register */
-				ctx->regs[ft] = val;
-			} else if (ft & 1) {
-				/* load to m.s. 32 bits */
-#ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				ctx->regs[(ft & ~1)] &= 0xffffffff;
-				ctx->regs[(ft & ~1)] |= val << 32;
-#endif
-			} else {
-				/* load to l.s. 32 bits */
-				ctx->regs[ft] &= ~0xffffffffLL;
-				ctx->regs[ft] |= val;
-			}
-		}
-		break;
-
-	case swc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			unsigned int val;
-			int ft = MIPSInst_RT(ir);
-			fpuemuprivate.stats.stores++;
-			if (xcp->cp0_status & ST0_FR) {
-				/* store whole register */
-				val = ctx->regs[ft];
-			} else if (ft & 1) {
-#ifdef SINGLE_ONLY_FPU
-				/* illegal register in single-float mode */
-				return SIGILL;
-#else
-				/* store from m.s. 32 bits */
-				val = ctx->regs[(ft & ~1)] >> 32;
-#endif
-			} else {
-				/* store from l.s. 32 bits */
-				val = ctx->regs[ft];
-			}
-			if (mips_put_word(xcp, va, val)) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-#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);
-			fpuemuprivate.stats.loads++;
-			if (err) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-
-	case swc1_op:
-		{
-			void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)])
-			    + MIPSInst_SIMM(ir);
-			fpuemuprivate.stats.stores++;
-			if (mips_put_word
-			    (xcp, va, ctx->regs[MIPSInst_RT(ir)])) {
-				fpuemuprivate.stats.errors++;
-				return SIGBUS;
-			}
-		}
-		break;
-	case ldc1_op:
-		{
-			void *va = REG_TO_VA(xcp->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;
-#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;
-#endif
-			if (err)
-				return SIGBUS;
-		}
-		break;
-
-	case sdc1_op:
-		{
-			void *va = REG_TO_VA(xcp->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]))
-				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]))
-				return SIGBUS;
-#endif
-		}
-		break;
-#endif
-
-	case cop1_op:
-		switch (MIPSInst_RS(ir)) {
-
-#ifdef CP0_STATUS_FR_SUPPORT
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case dmfc_op:
-			/* copregister fs -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				int fs = MIPSInst_RD(ir);
-				if (!(xcp->cp0_status & ST0_FR))
-					fs &= ~1;
-				xcp->regs[MIPSInst_RT(ir)] = ctx->regs[fs];
-			}
-			break;
-
-		case dmtc_op:
-			/* copregister fs <- rt */
-			{
-				fpureg_t value;
-				int fs = MIPSInst_RD(ir);
-				if (!(xcp->cp0_status & ST0_FR))
-					fs &= ~1;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
-				ctx->regs[fs] = value;
-			}
-			break;
-#endif
-
-		case mfc_op:
-			/* copregister rd -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				/* default value from l.s. 32 bits */
-				int value = ctx->regs[MIPSInst_RD(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)) {
-						/* move from m.s. 32 bits */
-						value =
-						    ctx->
-						    regs[MIPSInst_RD(ir) &
-							 ~1] >> 32;
-					}
-#endif
-				}
-				xcp->regs[MIPSInst_RT(ir)] = value;
-			}
-			break;
-
-		case mtc_op:
-			/* copregister rd <- rt */
-			{
-				fpureg_t value;
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value =
-					    (unsigned int) xcp->
-					    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)) {
-						/* move to m.s. 32 bits */
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_RD(ir) &
-							  ~1)] |=
-						    value << 32;
-						break;
-					}
-#endif
-				}
-				/* move to l.s. 32 bits */
-				ctx->regs[MIPSInst_RD(ir)] &=
-				    ~0xffffffffLL;
-				ctx->regs[MIPSInst_RD(ir)] |= value;
-			}
-			break;
-#else
-
-		case mfc_op:
-			/* copregister rd -> gpr[rt] */
-			if (MIPSInst_RT(ir) != 0) {
-				unsigned value =
-				    ctx->regs[MIPSInst_RD(ir)];
-				xcp->regs[MIPSInst_RT(ir)] = value;
-			}
-			break;
-
-		case mtc_op:
-			/* copregister rd <- rt */
-			{
-				unsigned value;
-				value =
-				    (MIPSInst_RT(ir) ==
-				     0) ? 0 : xcp->regs[MIPSInst_RT(ir)];
-				ctx->regs[MIPSInst_RD(ir)] = value;
-			}
-			break;
-#endif
-
-		case cfc_op:
-			/* cop control register rd -> gpr[rt] */
-			{
-				unsigned value;
-
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
-					value = ctx->sr;
-#ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]<-csr=%08x\n",
-					     REG_TO_VA(xcp->cp0_epc),
-					     MIPSInst_RT(ir), value);
-#endif
-				} else if (MIPSInst_RD(ir) == FPCREG_RID)
-					value = 0;
-				else
-					value = 0;
-				if (MIPSInst_RT(ir))
-					xcp->regs[MIPSInst_RT(ir)] = value;
-			}
-			break;
-
-		case ctc_op:
-			/* copregister rd <- rt */
-			{
-				unsigned value;
-
-				if (MIPSInst_RT(ir) == 0)
-					value = 0;
-				else
-					value = xcp->regs[MIPSInst_RT(ir)];
-
-				/* we only have one writable control reg
-				 */
-				if (MIPSInst_RD(ir) == FPCREG_CSR) {
-#ifdef CSRTRACE
-					printk
-					    ("%p gpr[%d]->csr=%08x\n",
-					     REG_TO_VA(xcp->cp0_epc),
-					     MIPSInst_RT(ir), value);
-#endif
-					ctx->sr = value;
-					/* copy new rounding mode to ieee library state! */
-					ieee754_csr.rm =
-					    ieee_rm[value & 0x3];
-				}
-			}
-			break;
-
-		case bc_op:
-			if (xcp->cp0_cause & CAUSEF_BD) {
-				return SIGILL;
-			}
-			{
-				int likely = 0;
-
-#if __mips >= 4
-				cond =
-				    ctx->
-				    sr & fpucondbit[MIPSInst_RT(ir) >> 2];
-#else
-				cond = ctx->sr & FPU_CSR_COND;
-#endif
-				switch (MIPSInst_RT(ir) & 3) {
-				case bcfl_op:
-					likely = 1;
-				case bcf_op:
-					cond = !cond;
-					break;
-				case bctl_op:
-					likely = 1;
-				case bct_op:
-					break;
-				default:
-					/* thats an illegal instruction */
-					return SIGILL;
-				}
-
-				xcp->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);
-
-					ir =
-					    mips_get_word(xcp,
-							  REG_TO_VA(xcp->
-								    cp0_epc),
-							  &err);
-					if (err) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-
-					switch (MIPSInst_OPCODE(ir)) {
-					case lwc1_op:
-					case swc1_op:
-#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU)
-					case ldc1_op:
-					case sdc1_op:
-#endif
-					case cop1_op:
-#if __mips >= 4 && __mips != 32
-					case cop1x_op:
-#endif
-						/* its one of ours */
-						goto emul;
-#if __mips >= 4
-					case spec_op:
-						if (MIPSInst_FUNC(ir) ==
-						    movc_op) goto emul;
-						break;
-#endif
-					}
-
-					/* single step the non-cp1 instruction in the dslot */
-					return mips_dsemul(xcp, ir, contpc);
-				} else {
-					/* branch not taken */
-					if (likely)
-						/* branch likely nullifies dslot if not taken */
-						xcp->cp0_epc += 4;
-					/* else continue & execute dslot as normal insn */
-				}
-			}
-			break;
-
-		default:
-			if (!(MIPSInst_RS(ir) & 0x10)) {
-				return SIGILL;
-			}
-			/* a real fpu computation instruction */
-			{
-				int sig;
-				if ((sig = fpu_emu(xcp, ctx, ir)))
-					return sig;
-			}
-		}
-		break;
-
-#if __mips >= 4 && __mips != 32
-	case cop1x_op:
-		{
-			int sig;
-			if ((sig = fpux_emu(xcp, ctx, ir)))
-				return sig;
-		}
-		break;
-#endif
-
-#if __mips >= 4
-	case spec_op:
-		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)];
-		break;
-#endif
-
-	default:
-		return SIGILL;
-	}
-
-	/* we did it !! */
-	xcp->cp0_epc = VA_TO_REG(contpc);
-	xcp->cp0_cause &= ~CAUSEF_BD;
-	return 0;
-}
-
-/*
- * Emulate the arbritrary instruction ir at xcp->cp0_epc.  Required when
- * we have to emulate the instruction in a COP1 branch delay slot.  Do
- * not change cp0_epc due to the instruction
- *
- * According to the spec:
- * 1) it shouldnt be a branch :-)
- * 2) it can be a COP instruction :-(
- * 3) if we are tring to run a protected memory space we must take
- *    special care on memory access instructions :-(
- */
-
-/*
- * "Trampoline" return routine to catch exception following
- *  execution of delay-slot instruction execution.
- */
-
-int do_dsemulret(struct pt_regs *xcp)
-{
-#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;
-
-	return 0;
-}
-
-
-#define AdELOAD 0x8c000001	/* lw $0,1($0) */
-
-static int
-mips_dsemul(struct pt_regs *xcp, mips_instruction ir, vaddr_t cpc)
-{
-	mips_instruction *dsemul_insns;
-	mips_instruction forcetrap;
-	extern asmlinkage void handle_dsemulret(void);
-
-	if (ir == 0) {		/* a nop is easy */
-		xcp->cp0_epc = VA_TO_REG(cpc);
-		return 0;
-	}
-#ifdef DSEMUL_TRACE
-	printk("desemul %p %p\n", REG_TO_VA(xcp->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
-	 * multiprocessor support.  We flag the thread for special
-	 * handling in the unaligned access handler and force an
-	 * 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;
-
-	if (mips_put_word(xcp, &dsemul_insns[1], forcetrap)) {
-		fpuemuprivate.stats.errors++;
-		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);
-
-	return SIGILL;		/* force out of emulation loop */
-}
-
-/* 
- * Conversion table from MIPS compare ops 48-63
- * cond = ieee754dp_cmp(x,y,IEEE754_UN);
- */
-static const unsigned char cmptab[8] = {
-	0,					/* cmp_0 (sig) cmp_sf */
-	IEEE754_CUN,				/* cmp_un (sig) cmp_ngle */
-	IEEE754_CEQ,				/* cmp_eq (sig) cmp_seq */
-	IEEE754_CEQ | IEEE754_CUN,		/* cmp_ueq (sig) cmp_ngl  */
-	IEEE754_CLT,				/* cmp_olt (sig) cmp_lt */
-	IEEE754_CLT | IEEE754_CUN,		/* cmp_ult (sig) cmp_nge */
-	IEEE754_CLT | IEEE754_CEQ,		/* cmp_ole (sig) cmp_le */
-	IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
-};
-
-#define SIFROMREG(si,x)	((si) = ctx->regs[x])
-#define SITOREG(si,x)	(ctx->regs[x] = (int)(si))
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-#define DIFROMREG(di,x)	((di) = ctx->regs[x])
-#define DITOREG(di,x)	(ctx->regs[x] = (di))
-#endif
-
-#define SPFROMREG(sp,x)	((sp).bits = ctx->regs[x])
-#define SPTOREG(sp,x)	(ctx->regs[x] = (sp).bits)
-
-#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)
-#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])
-#define DPTOREG(dp,x) \
-  (ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32)
-#endif
-
-#if __mips >= 4 && __mips != 32
-
-/*
- * Additional MIPS4 instructions
- */
-
-static ieee754dp fpemu_dp_recip(ieee754dp d)
-{
-	return ieee754dp_div(ieee754dp_one(0), d);
-}
-
-static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
-{
-	return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
-}
-
-static ieee754sp fpemu_sp_recip(ieee754sp s)
-{
-	return ieee754sp_div(ieee754sp_one(0), s);
-}
-
-static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
-{
-	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));
-}
-
-static int
-fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-	 mips_instruction ir)
-{
-	unsigned rcsr = 0;	/* resulting csr */
-
-	fpuemuprivate.stats.cp1xops++;
-
-	switch (MIPSInst_FMA_FFMT(ir)) {
-	case s_fmt:		/* 0 */
-		{
-			ieee754sp(*handler) (ieee754sp, ieee754sp,
-					     ieee754sp);
-			ieee754sp fd, fr, fs, ft;
-
-			switch (MIPSInst_FUNC(ir)) {
-			case lwxc1_op:
-				{
-					void *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++;
-						return SIGBUS;
-					}
-					if (xcp->cp0_status & ST0_FR) {
-						/* load whole register */
-						ctx->
-						    regs[MIPSInst_FD(ir)] =
-						    val;
-					} else if (MIPSInst_FD(ir) & 1) {
-						/* load to m.s. 32 bits */
-#if defined(SINGLE_ONLY_FPU)
-						/* illegal register in single-float mode */
-						return SIGILL;
-#else
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] &=
-						    0xffffffff;
-						ctx->
-						    regs[
-							 (MIPSInst_FD(ir) &
-							  ~1)] |=
-						    val << 32;
-#endif
-					} else {
-						/* load to l.s. 32 bits */
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    &= ~0xffffffffLL;
-						ctx->
-						    regs[MIPSInst_FD(ir)]
-						    |= val;
-					}
-				}
-				break;
-
-			case swxc1_op:
-				{
-					void *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)];
-					} 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;
-#endif
-					} else {
-						/* store from l.s. 32 bits */
-						val =
-						    ctx->
-						    regs[MIPSInst_FS(ir)];
-					}
-					if (mips_put_word(xcp, va, val)) {
-						fpuemuprivate.stats.
-						    errors++;
-						return SIGBUS;
-					}
-				}
-				break;
-
-			case madd_s_op:
-				handler = fpemu_sp_madd;
-				goto scoptop;
-			case msub_s_op:
-				handler = fpemu_sp_msub;
-				goto scoptop;
-			case nmadd_s_op:
-				handler = fpemu_sp_nmadd;
-				goto scoptop;
-			case nmsub_s_op:
-				handler = fpemu_sp_nmsub;
-				goto scoptop;
-
-			      scoptop:
-				SPFROMREG(fr, MIPSInst_FR(ir));
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				SPTOREG(fd, MIPSInst_FD(ir));
-
-			      copcsr:
-				if (ieee754_cxtest(IEEE754_INEXACT))
-					rcsr |=
-					    FPU_CSR_INE_X | FPU_CSR_INE_S;
-				if (ieee754_cxtest(IEEE754_UNDERFLOW))
-					rcsr |=
-					    FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-				if (ieee754_cxtest(IEEE754_OVERFLOW))
-					rcsr |=
-					    FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-				if (ieee754_cxtest
-				    (IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-
-				ctx->sr =
-				    (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
-				if ((ctx->sr >> 5) & ctx->
-				    sr & FPU_CSR_ALL_E) {
-		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
-					return SIGFPE;
-				}
-
-				break;
-
-			default:
-				return SIGILL;
-			}
-		}
-		break;
-
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt:		/* 1 */
-		{
-			ieee754dp(*handler) (ieee754dp, ieee754dp,
-					     ieee754dp);
-			ieee754dp fd, fr, fs, ft;
-
-			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++;
-						return SIGBUS;
-					}
-				}
-				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++;
-						return SIGBUS;
-					}
-				}
-				break;
-
-			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;
-
-			      dcoptop:
-				DPFROMREG(fr, MIPSInst_FR(ir));
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-				fd = (*handler) (fr, fs, ft);
-				DPTOREG(fd, MIPSInst_FD(ir));
-				goto copcsr;
-
-			default:
-				return SIGILL;
-			}
-		}
-		break;
-#endif
-
-	case 0x7:		/* 7 */
-		{
-			if (MIPSInst_FUNC(ir) != pfetch_op) {
-				return SIGILL;
-			}
-			/* ignore prefx operation */
-		}
-		break;
-
-	default:
-		return SIGILL;
-	}
-
-	return 0;
-}
-#endif
-
-
-
-/*
- * Emulate a single COP1 arithmetic instruction.
- */
-static int
-fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
-	mips_instruction ir)
-{
-	int rfmt;		/* resulting format */
-	unsigned rcsr = 0;	/* resulting csr */
-	unsigned cond;
-	union {
-		ieee754dp d;
-		ieee754sp s;
-		int w;
-#if __mips64
-		long long l;
-#endif
-	} rv;			/* resulting value */
-
-	fpuemuprivate.stats.cp1ops++;
-	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
-
-	case s_fmt:{		/* 0 */
-		ieee754sp(*handler) ();
-
-		switch (MIPSInst_FUNC(ir)) {
-			/* binary ops */
-		case fadd_op:
-			handler = ieee754sp_add;
-			goto scopbop;
-		case fsub_op:
-			handler = ieee754sp_sub;
-			goto scopbop;
-		case fmul_op:
-			handler = ieee754sp_mul;
-			goto scopbop;
-		case fdiv_op:
-			handler = ieee754sp_div;
-			goto scopbop;
-
-			/* unary  ops */
-#if __mips >= 2 || __mips64
-		case fsqrt_op:
-			handler = ieee754sp_sqrt;
-			goto scopuop;
-#endif
-#if __mips >= 4 && __mips != 32
-		case frsqrt_op:
-			handler = fpemu_sp_rsqrt;
-			goto scopuop;
-		case frecip_op:
-			handler = fpemu_sp_recip;
-			goto scopuop;
-#endif
-#if __mips >= 4
-		case fmovc_op:
-			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
-			if (((ctx->sr & cond) != 0) !=
-			    ((MIPSInst_FT(ir) & 1) != 0))
-				return 0;
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-		case fmovz_op:
-			if (xcp->regs[MIPSInst_FT(ir)] != 0)
-				return 0;
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-		case fmovn_op:
-			if (xcp->regs[MIPSInst_FT(ir)] == 0)
-				return 0;
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-#endif
-		case fabs_op:
-			handler = ieee754sp_abs;
-			goto scopuop;
-		case fneg_op:
-			handler = ieee754sp_neg;
-			goto scopuop;
-		case fmov_op:
-			/* an easy one */
-			SPFROMREG(rv.s, MIPSInst_FS(ir));
-			break;
-			/* binary op on handler */
-scopbop:
-			{
-				ieee754sp fs, ft;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-
-				rv.s = (*handler) (fs, ft);
-				goto copcsr;
-			}
-scopuop:
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = (*handler) (fs);
-				goto copcsr;
-			}
-copcsr:
-			if (ieee754_cxtest(IEEE754_INEXACT))
-				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
-			if (ieee754_cxtest(IEEE754_UNDERFLOW))
-				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
-			if (ieee754_cxtest(IEEE754_OVERFLOW))
-				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
-			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
-				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
-			if (ieee754_cxtest
-				(IEEE754_INVALID_OPERATION)) rcsr |=
-					    FPU_CSR_INV_X | FPU_CSR_INV_S;
-				break;
-
-				/* unary conv ops */
-		case fcvts_op:
-			return SIGILL;	/* not defined */
-		case fcvtd_op:
-#if defined(SINGLE_ONLY_FPU)
-			return SIGILL;	/* not defined */
-#else
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = ieee754dp_fsp(fs);
-				rfmt = d_fmt;
-				goto copcsr;
-			}
-#endif
-		case fcvtw_op:
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.w = ieee754sp_tint(fs);
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-
-#if __mips >= 2 || __mips64
-		case fround_op:
-		case ftrunc_op:
-		case fceil_op:
-		case ffloor_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.w = ieee754sp_tint(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-#endif			/* __mips >= 2 */
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op:
-			{
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				rv.l = ieee754sp_tlong(fs);
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-
-		case froundl_op:
-		case ftruncl_op:
-		case fceill_op:
-		case ffloorl_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754sp fs;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.l = ieee754sp_tlong(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-#endif /* __mips64 && !fpu(single) */
-
-		default:
-			if (MIPSInst_FUNC(ir) >= fcmp_op) {
-				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
-				ieee754sp fs, ft;
-
-				SPFROMREG(fs, MIPSInst_FS(ir));
-				SPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]);
-				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION))
-					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
-				} else {
-					return SIGILL;
-				}
-				break;
-			}
-			break;
-		}
-
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt: {
-		ieee754dp(*handler) ();
-
-		switch (MIPSInst_FUNC(ir)) {
-			/* binary ops */
-		case fadd_op:
-			handler = ieee754dp_add;
-			goto dcopbop;
-		case fsub_op:
-			handler = ieee754dp_sub;
-			goto dcopbop;
-		case fmul_op:
-			handler = ieee754dp_mul;
-			goto dcopbop;
-		case fdiv_op:
-			handler = ieee754dp_div;
-			goto dcopbop;
-
-			/* unary  ops */
-#if __mips >= 2 || __mips64
-		case fsqrt_op:
-			handler = ieee754dp_sqrt;
-			goto dcopuop;
-#endif
-#if __mips >= 4 && __mips != 32
-		case frsqrt_op:
-			handler = fpemu_dp_rsqrt;
-			goto dcopuop;
-		case frecip_op:
-			handler = fpemu_dp_recip;
-			goto dcopuop;
-#endif
-#if __mips >= 4
-		case fmovc_op:
-			cond = fpucondbit[MIPSInst_FT(ir) >> 2];
-			if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0))
-				return 0;
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-		case fmovz_op:
-			if (xcp->regs[MIPSInst_FT(ir)] != 0)
-				return 0;
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-		case fmovn_op:
-			if (xcp->regs[MIPSInst_FT(ir)] == 0)
-				return 0;
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-#endif
-		case fabs_op:
-			handler = ieee754dp_abs;
-			goto dcopuop;
-		case fneg_op:
-			handler = ieee754dp_neg;
-			goto dcopuop;
-		case fmov_op:
-			/* an easy one */
-			DPFROMREG(rv.d, MIPSInst_FS(ir));
-			break;
-
-			/* binary op on handler */
-dcopbop:
-			{
-				ieee754dp fs, ft;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-
-				rv.d = (*handler) (fs, ft);
-				goto copcsr;
-			}
-dcopuop:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.d = (*handler) (fs);
-				goto copcsr;
-			}
-
-		/* unary conv ops */
-		case fcvts_op:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.s = ieee754sp_fdp(fs);
-				rfmt = s_fmt;
-				goto copcsr;
-			}
-		case fcvtd_op:
-			return SIGILL;	/* not defined */
-		case fcvtw_op:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.w = ieee754dp_tint(fs);	/* wrong */
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-
-#if __mips >= 2 || __mips64
-		case fround_op:
-		case ftrunc_op:
-		case fceil_op:
-		case ffloor_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.w = ieee754dp_tint(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = w_fmt;
-				goto copcsr;
-			}
-#endif
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-		case fcvtl_op:
-			{
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				rv.l = ieee754dp_tlong(fs);
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-
-		case froundl_op:
-		case ftruncl_op:
-		case fceill_op:
-		case ffloorl_op:
-			{
-				unsigned int oldrm = ieee754_csr.rm;
-				ieee754dp fs;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];
-				rv.l = ieee754dp_tlong(fs);
-				ieee754_csr.rm = oldrm;
-				rfmt = l_fmt;
-				goto copcsr;
-			}
-#endif /* __mips >= 3 && !fpu(single) */
-
-		default:
-			if (MIPSInst_FUNC(ir) >= fcmp_op) {
-				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
-				ieee754dp fs, ft;
-
-				DPFROMREG(fs, MIPSInst_FS(ir));
-				DPFROMREG(ft, MIPSInst_FT(ir));
-				rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]);
-				rfmt = -1;
-				if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION))
-					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
-			} else {
-				return SIGILL;
-			}
-			break;
-		}
-		break;
-	}
-#endif				/* !defined(SINGLE_ONLY_FPU) */
-
-	case w_fmt: {
-		switch (MIPSInst_FUNC(ir)) {
-		case fcvts_op:
-			/* convert word to single precision real */
-			rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = s_fmt;
-			goto copcsr;
-#if !defined(SINGLE_ONLY_FPU)
-		case fcvtd_op:
-			/* convert word to double precision real */
-			rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = d_fmt;
-			goto copcsr;
-#endif
-		default:
-			return SIGILL;
-		}
-		break;
-	}
-
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-	case l_fmt: {
-		switch (MIPSInst_FUNC(ir)) {
-		case fcvts_op:
-			/* convert long to single precision real */
-			rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = s_fmt;
-			goto copcsr;
-		case fcvtd_op:
-			/* convert long to double precision real */
-			rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]);
-			rfmt = d_fmt;
-			goto copcsr;
-		default:
-			return SIGILL;
-		}
-		break;
-	}
-#endif
-
-	default:
-		return SIGILL;
-	}
-
-	/*
-	 * Update the fpu CSR register for this operation.
-	 * If an exception is required, generate a tidy SIGFPE exception,
-	 * without updating the result register.
-	 * Note: cause exception bits do not accumulate, they are rewritten
-	 * for each op; only the flag/sticky bits accumulate.
-	 */
-	ctx->sr = (ctx->sr & ~FPU_CSR_ALL_X) | rcsr;
-	if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) {
-		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */
-		return SIGFPE;
-	}
-
-	/* 
-	 * Now we can safely write the result back to the register file.
-	 */
-	switch (rfmt) {
-	case -1: {
-#if __mips >= 4
-		cond = fpucondbit[MIPSInst_FD(ir) >> 2];
-#else
-		cond = FPU_CSR_COND;
-#endif
-		if (rv.w)
-			ctx->sr |= cond;
-		else
-			ctx->sr &= ~cond;
-		break;
-	}
-#if !defined(SINGLE_ONLY_FPU)
-	case d_fmt:
-		DPTOREG(rv.d, MIPSInst_FD(ir));
-		break;
-#endif
-	case s_fmt:
-		SPTOREG(rv.s, MIPSInst_FD(ir));
-		break;
-	case w_fmt:
-		SITOREG(rv.w, MIPSInst_FD(ir));
-		break;
-#if __mips64 && !defined(SINGLE_ONLY_FPU)
-	case l_fmt:
-		DITOREG(rv.l, MIPSInst_FD(ir));
-		break;
-#endif
-	default:
-		return SIGILL;
-	}
-
-	return 0;
-}
-
-
-/*
- * Emulate the floating point instruction at EPC, and continue
- * to run until we hit a non-fp instruction, or a backward
- * branch.  This cuts down dramatically on the per instruction 
- * exception overhead.
- */
-int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp)
-{
-	struct mips_fpu_soft_struct *ctx = &current->thread.fpu.soft;
-	unsigned long oldepc, prevepc;
-	unsigned int insn;
-	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) {
-			fpuemuprivate.stats.errors++;
-			return SIGBUS;
-		}
-		if (insn != 0)
-			sig = cop1Emulate(xcptno, xcp, ctx);
-		else
-			xcp->cp0_epc += 4;	/* skip nops */
-
-		if (mips_cpu.options & MIPS_CPU_FPU)
-			break;
-	} while (xcp->cp0_epc > prevepc && sig == 0);
-
-	/* SIGILL indicates a non-fpu instruction */
-	if (sig == SIGILL && xcp->cp0_epc != oldepc)
-		/* but if epc has advanced, then ignore it */
-		sig = 0;
-
-	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(xcptno, 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.
-		 */
-#if 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 -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_add.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_add.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_add.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_add.c	Wed Dec 31 16:00:00 1969
@@ -1,186 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y)
-{
-	COMPXDP;
-	COMPYDP;
-
-	EXPLODEXDP;
-	EXPLODEYDP;
-
-	CLEARCX;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "add", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs == ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		else
-			return ieee754dp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-
-		/* FALL THROUGH */
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-
-	/* provide guard,round and stick bit space */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		ym = XDPSRS(ym, s);
-		ye += s;
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		xm = XDPSRS(xm, s);
-		xe += s;
-	}
-	assert(xe == ye);
-	assert(xe <= DP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 * leaving result in xm,xs,xe
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (DP_MBITS + 1 + 3)) {	/* carry out */
-			xm = XDPSRS1(xm);
-			xe++;
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0)
-			return ieee754dp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-		/* normalize to rounding precision */
-		while ((xm >> (DP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-
-	}
-	DPNORMRET2(xs, xe, xm, "add", x, y);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_cmp.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_cmp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_cmp.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_cmp.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp)
-{
-	CLEARCX;
-
-	if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
-		if (cmp & IEEE754_CUN)
-			return 1;
-		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
-				return ieee754si_xcpt(0, "fcmpf", x);
-		}
-		return 0;
-	} else {
-		long long int vx = x.bits;
-		long long int vy = y.bits;
-
-		if (vx < 0)
-			vx = -vx ^ DP_SIGN_BIT;
-		if (vy < 0)
-			vy = -vy ^ DP_SIGN_BIT;
-
-		if (vx < vy)
-			return (cmp & IEEE754_CLT) != 0;
-		else if (vx == vy)
-			return (cmp & IEEE754_CEQ) != 0;
-		else
-			return (cmp & IEEE754_CGT) != 0;
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_div.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_div.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_div.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_div.c	Wed Dec 31 16:00:00 1969
@@ -1,160 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y)
-{
-	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);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return ieee754dp_zero(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return ieee754dp_inf(xs ^ ys);
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_ZERO_DIVIDE);
-		return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return ieee754dp_zero(xs == ys ? 0 : 1);
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-
-	/* provide rounding space */
-	xm <<= 3;
-	ym <<= 3;
-
-	{
-		/* now the dirty work */
-
-		unsigned long long rm = 0;
-		int re = xe - ye;
-		unsigned long long bm;
-
-		for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
-			if (xm >= ym) {
-				xm -= ym;
-				rm |= bm;
-				if (xm == 0)
-					break;
-			}
-			xm <<= 1;
-		}
-		rm <<= 1;
-		if (xm)
-			rm |= 1;	/* have remainder, set sticky */
-
-		assert(rm);
-
-		/* normalise rm to rounding precision ?
-		 */
-		while ((rm >> (DP_MBITS + 3)) == 0) {
-			rm <<= 1;
-			re--;
-		}
-
-		DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_fint.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_fint.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_fint.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_fint.c	Wed Dec 31 16:00:00 1969
@@ -1,78 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_fint(int x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754dp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754dp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754dp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1 << 31))
-			xm = ((unsigned) 1 << 31);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-
-#if 1
-	/* normalize - result can never be inexact or overflow */
-	xe = DP_MBITS;
-	while ((xm >> DP_MBITS) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-#else
-	/* normalize */
-	xe = DP_MBITS + 3;
-	while ((xm >> (DP_MBITS + 3)) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	DPNORMRET1(xs, xe, xm, "fint", x);
-#endif
-}
-
-ieee754dp ieee754dp_funs(unsigned int u)
-{
-	if ((int) u < 0)
-		return ieee754dp_add(ieee754dp_1e31(),
-				     ieee754dp_fint(u & ~(1 << 31)));
-	return ieee754dp_fint(u);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_flong.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_flong.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_flong.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_flong.c	Wed Dec 31 16:00:00 1969
@@ -1,76 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_flong(long long x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754dp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754dp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754dp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1ULL << 63))
-			xm = (1ULL << 63);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-
-	/* normalize */
-	xe = DP_MBITS + 3;
-	if (xm >> (DP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits */
-		while (xm >> (DP_MBITS + 1 + 3)) {
-			XDPSRSX1();
-		}
-	} else {
-		/* normalize in grs extended double precision */
-		while ((xm >> (DP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	DPNORMRET1(xs, xe, xm, "dp_flong", x);
-}
-
-ieee754dp ieee754dp_fulong(unsigned long long u)
-{
-	if ((long long) u < 0)
-		return ieee754dp_add(ieee754dp_1e63(),
-				     ieee754dp_flong(u & ~(1ULL << 63)));
-	return ieee754dp_flong(u);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_frexp.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_frexp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_frexp.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_frexp.c	Wed Dec 31 16:00:00 1969
@@ -1,53 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-/* close to ieeep754dp_logb 
-*/
-ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
-{
-	COMPXDP;
-	CLEARCX;
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*eptr = 0;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	*eptr = xe + 1;
-	return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_fsp.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_fsp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_fsp.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_fsp.c	Wed Dec 31 16:00:00 1969
@@ -1,70 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_fsp(ieee754sp x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		return ieee754dp_nanxcpt(builddp(xs,
-						 DP_EMAX + 1 + DP_EBIAS,
-						 ((unsigned long long) xm
-						  << (DP_MBITS -
-						      SP_MBITS))), "fsp",
-					 x);
-	case IEEE754_CLASS_INF:
-		return ieee754dp_inf(xs);
-	case IEEE754_CLASS_ZERO:
-		return ieee754dp_zero(xs);
-	case IEEE754_CLASS_DNORM:
-		/* normalize */
-		while ((xm >> SP_MBITS) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-
-	/* CANT possibly overflow,underflow, or need rounding
-	 */
-
-	/* drop the hidden bit */
-	xm &= ~SP_HIDDEN_BIT;
-
-	return builddp(xs, xe + DP_EBIAS,
-		       (unsigned long long) xm << (DP_MBITS - SP_MBITS));
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_logb.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_logb.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_logb.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_logb.c	Wed Dec 31 16:00:00 1969
@@ -1,54 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_logb(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754dp_nanxcpt(x, "logb", x);
-	case IEEE754_CLASS_QNAN:
-		return x;
-	case IEEE754_CLASS_INF:
-		return ieee754dp_inf(0);
-	case IEEE754_CLASS_ZERO:
-		return ieee754dp_inf(1);
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	return ieee754dp_fint(xe);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_modf.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_modf.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_modf.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_modf.c	Wed Dec 31 16:00:00 1969
@@ -1,80 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-/* modf function is always exact for a finite number
-*/
-ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*ip = x;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		/* far to small */
-		*ip = ieee754dp_zero(xs);
-		return x;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe < 0) {
-		*ip = ieee754dp_zero(xs);
-		return x;
-	}
-	if (xe >= DP_MBITS) {
-		*ip = x;
-		return ieee754dp_zero(xs);
-	}
-	/* generate ipart mantissa by clearing bottom bits 
-	 */
-	*ip = builddp(xs, xe + DP_EBIAS,
-		      ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
-		      ~DP_HIDDEN_BIT);
-
-	/* generate fpart mantissa by clearing top bits
-	 * and normalizing (must be able to normalize)
-	 */
-	xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe));
-	if (xm == 0)
-		return ieee754dp_zero(xs);
-
-	while ((xm >> DP_MBITS) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_mul.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_mul.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_mul.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_mul.c	Wed Dec 31 16:00:00 1969
@@ -1,180 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y)
-{
-	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);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		return ieee754dp_inf(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return ieee754dp_zero(xs ^ ys);
-
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* rm = xm * ym, re = xe+ye basicly */
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-	{
-		int re = xe + ye;
-		int rs = xs ^ ys;
-		unsigned long long rm;
-
-		/* shunt to top of word */
-		xm <<= 64 - (DP_MBITS + 1);
-		ym <<= 64 - (DP_MBITS + 1);
-
-		/* multiply 32bits xm,ym to give high 32bits rm with stickness
-		 */
-
-		/* 32 * 32 => 64 */
-#define DPXMULT(x,y)	((unsigned long long)(x) * (unsigned long long)y)
-
-		{
-			unsigned lxm = xm;
-			unsigned hxm = xm >> 32;
-			unsigned lym = ym;
-			unsigned hym = ym >> 32;
-			unsigned long long lrm;
-			unsigned long long hrm;
-
-			lrm = DPXMULT(lxm, lym);
-			hrm = DPXMULT(hxm, hym);
-
-			{
-				unsigned long long t = DPXMULT(lxm, hym);
-				{
-					unsigned long long at =
-					    lrm + (t << 32);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 32);
-			}
-
-			{
-				unsigned long long t = DPXMULT(hxm, lym);
-				{
-					unsigned long long at =
-					    lrm + (t << 32);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 32);
-			}
-			rm = hrm | (lrm != 0);
-		}
-
-		/*
-		 * sticky shift down to normal rounding precision
-		 */
-		if ((signed long long) rm < 0) {
-			rm =
-			    (rm >> (64 - (DP_MBITS + 1 + 3))) |
-			    ((rm << (DP_MBITS + 1 + 3)) != 0);
-			re++;
-		} else {
-			rm =
-			    (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) |
-			    ((rm << (DP_MBITS + 1 + 3 + 1)) != 0);
-		}
-		assert(rm & (DP_HIDDEN_BIT << 3));
-		DPNORMRET2(rs, re, rm, "mul", x, y);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_scalb.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_scalb.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_scalb.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_scalb.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_scalb(ieee754dp x, int n)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754dp_nanxcpt(x, "scalb", x, n);
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		return x;
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
-}
-
-
-ieee754dp ieee754dp_ldexp(ieee754dp x, int n)
-{
-	return ieee754dp_scalb(x, n);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_simple.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_simple.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_simple.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_simple.c	Wed Dec 31 16:00:00 1969
@@ -1,66 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-int ieee754dp_finite(ieee754dp x)
-{
-	return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
-}
-
-ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y)
-{
-	CLEARCX;
-	DPSIGN(x) = DPSIGN(y);
-	return x;
-}
-
-
-ieee754dp ieee754dp_neg(ieee754dp x)
-{
-	CLEARCX;
-
-	if (ieee754dp_isnan(x))	/* but not infinity */
-		return ieee754dp_nanxcpt(x, "neg", x);
-
-	/* quick fix up */
-	DPSIGN(x) ^= 1;
-	return x;
-}
-
-
-ieee754dp ieee754dp_abs(ieee754dp x)
-{
-	CLEARCX;
-
-	if (ieee754dp_isnan(x))	/* but not infinity */
-		return ieee754dp_nanxcpt(x, "abs", x);
-
-	/* quick fix up */
-	DPSIGN(x) = 0;
-	return x;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_sqrt.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_sqrt.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_sqrt.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_sqrt.c	Wed Dec 31 16:00:00 1969
@@ -1,167 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision square root
- */
-/*
- * 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.
- *
- *  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 "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,
-	85215, 83599, 71378, 60428, 50647, 41945, 34246,
-	27478, 21581, 16499, 12183, 8588, 5674, 3403,
-	1742, 661, 130
-};
-
-ieee754dp ieee754dp_sqrt(ieee754dp x)
-{
-	struct ieee754_csr oldcsr;
-	ieee754dp y, z, t;
-	unsigned scalx, yh;
-	COMPXDP;
-
-	EXPLODEXDP;
-
-	/* 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_ZERO:
-		/* sqrt(0) = 0 */
-		return x;
-	case IEEE754_CLASS_INF:
-		if (xs)
-			/* sqrt(-Inf) = Nan */
-			return ieee754dp_nanxcpt(nan, "sqrt");
-		/* sqrt(+Inf) = Inf */
-		return x;
-	case IEEE754_CLASS_DNORM:
-		DPDNORMX;
-		/* fall through */
-	case IEEE754_CLASS_NORM:
-		if (xs)
-			/* sqrt(-x) = Nan */
-			return ieee754dp_nanxcpt(nan, "sqrt");
-		break;
-	}
-
-	/* save old csr; switch off INX enable & flag; set RN rounding */
-	oldcsr = ieee754_csr;
-	ieee754_csr.mx &= ~IEEE754_INEXACT;
-	ieee754_csr.sx &= ~IEEE754_INEXACT;
-	ieee754_csr.rm = IEEE754_RN;
-
-	/* adjust exponent to prevent overflow */
-	scalx = 0;
-	if (xe > 512) {		/* x > 2**-512? */
-		xe -= 512;	/* x = x / 2**512 */
-		scalx += 256;
-	} else if (xe < -512) {	/* x < 2**-512? */
-		xe += 512;	/* x = x * 2**512 */
-		scalx -= 256;
-	}
-
-	y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-
-	/* magic initial approximation to almost 8 sig. bits */
-	yh = y.bits >> 32;
-	yh = (yh >> 1) + 0x1ff80000;
-	yh = yh - table[(yh >> 15) & 31];
-	y.bits = ((unsigned long long) yh << 32) | (y.bits & 0xffffffff);
-
-	/* Heron's rule once with correction to improve to ~18 sig. bits */
-	/* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
-	t = ieee754dp_div(x, y);
-	y = ieee754dp_add(y, t);
-	y.bits -= 0x0010000600000000LL;
-	y.bits &= 0xffffffff00000000LL;
-
-	/* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
-	/* t=y*y; z=t;  pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
-	z = t = ieee754dp_mul(y, y);
-	t.parts.bexp += 0x001;
-	t = ieee754dp_add(t, z);
-	z = ieee754dp_mul(ieee754dp_sub(x, z), y);
-
-	/* t=z/(t+x) ;  pt[n0]+=0x00100000; y+=t; */
-	t = ieee754dp_div(z, ieee754dp_add(t, x));
-	t.parts.bexp += 0x001;
-	y = ieee754dp_add(y, t);
-
-	/* twiddle last bit to force y correctly rounded */
-
-	/* set RZ, clear INEX flag */
-	ieee754_csr.rm = IEEE754_RZ;
-	ieee754_csr.sx &= ~IEEE754_INEXACT;
-
-	/* t=x/y; ...chopped quotient, possibly inexact */
-	t = ieee754dp_div(x, y);
-
-	if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) {
-
-		if (!(ieee754_csr.sx & IEEE754_INEXACT))
-			/* t = t-ulp */
-			t.bits -= 1;
-
-		/* add inexact to result status */
-		oldcsr.cx |= IEEE754_INEXACT;
-		oldcsr.sx |= IEEE754_INEXACT;
-
-		switch (oldcsr.rm) {
-		case IEEE754_RP:
-			y.bits += 1;
-			/* drop through */
-		case IEEE754_RN:
-			t.bits += 1;
-			break;
-		}
-
-		/* y=y+t; ...chopped sum */
-		y = ieee754dp_add(y, t);
-
-		/* adjust scalx for correctly rounded sqrt(x) */
-		scalx -= 1;
-	}
-
-	/* py[n0]=py[n0]+scalx; ...scale back y */
-	y.parts.bexp += scalx;
-
-	/* restore rounding mode, possibly set inexact */
-	ieee754_csr = oldcsr;
-
-	return y;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_sub.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_sub.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_sub.c	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_sub.c	Wed Dec 31 16:00:00 1969
@@ -1,194 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y)
-{
-	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);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs != ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-		return ieee754dp_inf(ys ^ 1);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs != ys)
-			return x;
-		else
-			return ieee754dp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		/* quick fix up */
-		DPSIGN(y) ^= 1;
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		DPDNORMX;
-		/* FAAL THOROUGH */
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		/* normalize ym,ye */
-		DPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		/* normalize xm,xe */
-		DPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* flip sign of y and handle as add */
-	ys ^= 1;
-
-	assert(xm & DP_HIDDEN_BIT);
-	assert(ym & DP_HIDDEN_BIT);
-
-
-	/* provide guard,round and stick bit dpace */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		ym = XDPSRS(ym, s);
-		ye += s;
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		xm = XDPSRS(xm, s);
-		xe += s;
-	}
-	assert(xe == ye);
-	assert(xe <= DP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (DP_MBITS + 1 + 3)) {	/* carry out */
-			xm = XDPSRS1(xm);	/* shift preserving sticky */
-			xe++;
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0) {
-			if (ieee754_csr.rm == IEEE754_RD)
-				return ieee754dp_zero(1);	/* round negative inf. => sign = -1 */
-			else
-				return ieee754dp_zero(0);	/* other round modes   => sign = 1 */
-		}
-
-		/* normalize to rounding precision 
-		 */
-		while ((xm >> (DP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	DPNORMRET2(xs, xe, xm, "sub", x, y);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_tint.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_tint.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_tint.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_tint.c	Wed Dec 31 16:00:00 1969
@@ -1,88 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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/kernel.h>
-#include "ieee754dp.h"
-
-int ieee754dp_tint(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	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);
-	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_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);
-	}
-	/* oh gawd */
-	if (xe > DP_MBITS) {
-		xm <<= xe - DP_MBITS;
-	} else if (xe < DP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= DP_MBITS - xe;
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned int ieee754dp_tuns(ieee754dp x)
-{
-	ieee754dp hb = ieee754dp_1e31();
-
-	/* what if x < 0 ?? */
-	if (ieee754dp_lt(x, hb))
-		return (unsigned) ieee754dp_tint(x);
-
-	return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) |
-	    ((unsigned) 1 << 31);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/dp_tlong.c linux-2.4.20-pre7/arch/mips64/math-emu/dp_tlong.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/dp_tlong.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/dp_tlong.c	Wed Dec 31 16:00:00 1969
@@ -1,141 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-long long ieee754dp_tlong(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	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);
-		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_NORM:
-		break;
-	}
-	if (xe >= 63) {
-		SETCX(IEEE754_OVERFLOW);
-		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;
-		}
-		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)) {
-				xm++;
-			}
-		} else if (round && !sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)
-			    || (ieee754_csr.rm == IEEE754_RN && odd)) {
-				xm++;
-			}
-		} else if (round && sticky) {
-			if ((ieee754_csr.rm == IEEE754_RU && !xs)
-			    || (ieee754_csr.rm == IEEE754_RD && xs)
-			    || (ieee754_csr.rm == IEEE754_RN)) {
-				xm++;
-			}
-		}
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned long long ieee754dp_tulong(ieee754dp x)
-{
-	ieee754dp hb = ieee754dp_1e63();
-
-	/* what if x < 0 ?? */
-	if (ieee754dp_lt(x, hb))
-		return (unsigned long long) ieee754dp_tlong(x);
-
-	return (unsigned long long) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
-	    (1ULL << 63);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754.c linux-2.4.20-pre7/arch/mips64/math-emu/ieee754.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754.c	Thu Sep 12 20:01:31 2002
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754.c	Wed Dec 31 16:00:00 1969
@@ -1,138 +0,0 @@
-/* ieee754 floating point arithmetic
- * single and double precision
- *
- * BUGS
- * not much dp done
- * doesn't generate IEEE754_INEXACT
- *
- */
-/*
- * 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.
- *
- *  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 "ieee754int.h"
-
-#define DP_EBIAS	1023
-#define DP_EMIN		(-1022)
-#define DP_EMAX		1023
-
-#define SP_EBIAS	127
-#define SP_EMIN		(-126)
-#define SP_EMAX		127
-
-/* indexed by class */
-const char *const ieee754_cname[] = {
-	"Normal",
-	"Zero",
-	"Denormal",
-	"Infinity",
-	"QNaN",
-	"SNaN",
-};
-
-/* the control status register 
-*/
-struct ieee754_csr ieee754_csr;
-
-/* special constants
-*/
-
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
-#define SPSTR(s,b,m) {m,b,s}
-#define DPSTR(s,b,mh,ml) {ml,mh,b,s}
-#endif
-
-#ifdef __MIPSEB__
-#define SPSTR(s,b,m) {s,b,m}
-#define DPSTR(s,b,mh,ml) {s,b,mh,ml}
-#endif
-
-const struct ieee754dp_konst __ieee754dp_spcvals[] = {
-	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* + zero   */
-	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0),	/* - zero   */
-	DPSTR(0, DP_EBIAS, 0, 0),	/* + 1.0   */
-	DPSTR(1, DP_EBIAS, 0, 0),	/* - 1.0   */
-	DPSTR(0, 3 + DP_EBIAS, 0x40000, 0),	/* + 10.0   */
-	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 + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* + max */
-	DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF),	/* - max */
-	DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0),	/* + min normal */
-	DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0),	/* - min normal */
-	DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* + min denormal */
-	DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1),	/* - min denormal */
-	DPSTR(0, 31 + DP_EBIAS, 0, 0),	/* + 1.0e31 */
-	DPSTR(0, 63 + DP_EBIAS, 0, 0),	/* + 1.0e63 */
-};
-
-const struct ieee754sp_konst __ieee754sp_spcvals[] = {
-	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0),	/* + zero   */
-	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0),	/* - zero   */
-	SPSTR(0, SP_EBIAS, 0),	/* + 1.0   */
-	SPSTR(1, SP_EBIAS, 0),	/* - 1.0   */
-	SPSTR(0, 3 + SP_EBIAS, 0x200000),	/* + 10.0   */
-	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 + SP_EBIAS, 0x7FFFFF),	/* + max normal */
-	SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF),	/* - max normal */
-	SPSTR(0, SP_EMIN + SP_EBIAS, 0),	/* + min normal */
-	SPSTR(1, SP_EMIN + SP_EBIAS, 0),	/* - min normal */
-	SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1),	/* + min denormal */
-	SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1),	/* - min denormal */
-	SPSTR(0, 31 + SP_EBIAS, 0),	/* + 1.0e31 */
-	SPSTR(0, 63 + SP_EBIAS, 0),	/* + 1.0e63 */
-};
-
-
-int ieee754si_xcpt(int r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	if (!TSTX())
-		return r;
-	ax.op = op;
-	ax.rt = IEEE754_RT_SI;
-	ax.rv.si = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.si;
-}
-
-long long ieee754di_xcpt(long long r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	if (!TSTX())
-		return r;
-	ax.op = op;
-	ax.rt = IEEE754_RT_DI;
-	ax.rv.di = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.di;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754.h linux-2.4.20-pre7/arch/mips64/math-emu/ieee754.h
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754.h	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754.h	Wed Dec 31 16:00:00 1969
@@ -1,490 +0,0 @@
-/* single and double precision fp ops
- * missing extended precision.
-*/
-/*
- * 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.
- *
- *  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.
- *
- * ########################################################################
- */
-
-/**************************************************************************
- *  Nov 7, 2000
- *  Modification to allow integration with Linux kernel 
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
- *************************************************************************/
-
-#ifdef __KERNEL__
-/* Going from Algorithmics to Linux native environment, add this */
-#include <linux/types.h>
-
-/* 
- * Not very pretty, but the Linux kernel's normal va_list definition 
- * does not allow it to be used as a structure element, as it is here.
- */
-#ifndef _STDARG_H
-#include <stdarg.h>
-#endif
-
-#else
-
-/* Note that __KERNEL__ is taken to mean Linux kernel */
-
-#if #system(OpenBSD)
-#include <machine/types.h>
-#endif
-#include <machine/endian.h>
-
-#endif				/* __KERNEL__ */
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
-struct ieee754dp_konst {
-	unsigned mantlo:32;
-	unsigned manthi:20;
-	unsigned bexp:11;
-	unsigned sign:1;
-};
-struct ieee754sp_konst {
-	unsigned mant:23;
-	unsigned bexp:8;
-	unsigned sign:1;
-};
-
-typedef union _ieee754dp {
-	struct ieee754dp_konst oparts;
-	struct {
-		unsigned long long mant:52;
-		unsigned int bexp:11;
-		unsigned int sign:1;
-	} parts;
-	unsigned long long bits;
-	double d;
-} ieee754dp;
-
-typedef union _ieee754sp {
-	struct ieee754sp_konst parts;
-	float f;
-	unsigned long bits;
-} ieee754sp;
-#endif
-
-#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
-struct ieee754dp_konst {
-	unsigned sign:1;
-	unsigned bexp:11;
-	unsigned manthi:20;
-	unsigned mantlo:32;
-};
-typedef union _ieee754dp {
-	struct ieee754dp_konst oparts;
-	struct {
-		unsigned int sign:1;
-		unsigned int bexp:11;
-		unsigned long long mant:52;
-	} parts;
-	double d;
-	unsigned long long bits;
-} ieee754dp;
-
-struct ieee754sp_konst {
-	unsigned sign:1;
-	unsigned bexp:8;
-	unsigned mant:23;
-};
-
-typedef union _ieee754sp {
-	struct ieee754sp_konst parts;
-	float f;
-	unsigned long bits;
-} ieee754sp;
-#endif
-
-/*
- * single precision (often aka float)
-*/
-int ieee754sp_finite(ieee754sp x);
-int ieee754sp_class(ieee754sp x);
-
-ieee754sp ieee754sp_abs(ieee754sp x);
-ieee754sp ieee754sp_neg(ieee754sp x);
-ieee754sp ieee754sp_scalb(ieee754sp x, int);
-ieee754sp ieee754sp_logb(ieee754sp x);
-
-/* x with sign of y */
-ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
-
-ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
-ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
-ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
-ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
-
-ieee754sp ieee754sp_fint(int x);
-ieee754sp ieee754sp_funs(unsigned x);
-ieee754sp ieee754sp_flong(long long x);
-ieee754sp ieee754sp_fulong(unsigned long long x);
-ieee754sp ieee754sp_fdp(ieee754dp x);
-
-int ieee754sp_tint(ieee754sp x);
-unsigned int ieee754sp_tuns(ieee754sp x);
-long long ieee754sp_tlong(ieee754sp x);
-unsigned long long ieee754sp_tulong(ieee754sp x);
-
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop);
-/*
- * basic sp math
- */
-ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
-ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
-ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
-
-ieee754sp ieee754sp_ceil(ieee754sp x);
-ieee754sp ieee754sp_floor(ieee754sp x);
-ieee754sp ieee754sp_trunc(ieee754sp x);
-
-ieee754sp ieee754sp_sqrt(ieee754sp x);
-
-/*
- * double precision (often aka double)
-*/
-int ieee754dp_finite(ieee754dp x);
-int ieee754dp_class(ieee754dp x);
-
-/* x with sign of y */
-ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
-
-ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
-ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
-ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
-ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
-
-ieee754dp ieee754dp_abs(ieee754dp x);
-ieee754dp ieee754dp_neg(ieee754dp x);
-ieee754dp ieee754dp_scalb(ieee754dp x, int);
-
-/* return exponent as integer in floating point format 
- */
-ieee754dp ieee754dp_logb(ieee754dp x);
-
-ieee754dp ieee754dp_fint(int x);
-ieee754dp ieee754dp_funs(unsigned x);
-ieee754dp ieee754dp_flong(long long x);
-ieee754dp ieee754dp_fulong(unsigned long long x);
-ieee754dp ieee754dp_fsp(ieee754sp x);
-
-ieee754dp ieee754dp_ceil(ieee754dp x);
-ieee754dp ieee754dp_floor(ieee754dp x);
-ieee754dp ieee754dp_trunc(ieee754dp x);
-
-int ieee754dp_tint(ieee754dp x);
-unsigned int ieee754dp_tuns(ieee754dp x);
-long long ieee754dp_tlong(ieee754dp x);
-unsigned long long ieee754dp_tulong(ieee754dp x);
-
-int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop);
-/*
- * basic sp math
- */
-ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
-ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
-ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
-
-ieee754dp ieee754dp_ceil(ieee754dp x);
-ieee754dp ieee754dp_floor(ieee754dp x);
-ieee754dp ieee754dp_trunc(ieee754dp x);
-
-ieee754dp ieee754dp_sqrt(ieee754dp x);
-
-
-
-/* 5 types of floating point number 
-*/
-#define IEEE754_CLASS_NORM	0x00
-#define IEEE754_CLASS_ZERO	0x01
-#define IEEE754_CLASS_DNORM	0x02
-#define IEEE754_CLASS_INF	0x03
-#define IEEE754_CLASS_SNAN	0x04
-#define IEEE754_CLASS_QNAN	0x05
-extern const char *const ieee754_cname[];
-
-/* exception numbers */
-#define IEEE754_INEXACT			0x01
-#define IEEE754_UNDERFLOW		0x02
-#define IEEE754_OVERFLOW		0x04
-#define IEEE754_ZERO_DIVIDE		0x08
-#define IEEE754_INVALID_OPERATION	0x10
-
-/* cmp operators
-*/
-#define IEEE754_CLT	0x01
-#define IEEE754_CEQ	0x02
-#define IEEE754_CGT	0x04
-#define IEEE754_CUN	0x08
-
-/* rounding mode 
-*/
-#define IEEE754_RN	0	/* round to nearest */
-#define IEEE754_RZ	1	/* round toward zero  */
-#define IEEE754_RD	2	/* round toward -Infinity */
-#define IEEE754_RU	3	/* round toward +Infinity */
-
-/* other naming */
-#define IEEE754_RM	IEEE754_RD
-#define IEEE754_RP	IEEE754_RU
-
-/* "normal" comparisons
-*/
-static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CEQ);
-}
-
-static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
-}
-
-static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CLT);
-}
-
-static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
-}
-
-static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CGT);
-}
-
-
-static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
-{
-	return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
-}
-
-static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CEQ);
-}
-
-static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y,
-			     IEEE754_CLT | IEEE754_CGT | IEEE754_CUN);
-}
-
-static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CLT);
-}
-
-static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
-}
-
-static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CGT);
-}
-
-static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
-{
-	return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
-}
-
-
-/* like strtod
-*/
-ieee754dp ieee754dp_fstr(const char *s, char **endp);
-char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
-
-
-/* the control status register 
-*/
-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 */
-	unsigned sx:5;		/* exceptions total */
-	unsigned rm:2;		/* current rounding mode */
-};
-extern struct ieee754_csr ieee754_csr;
-
-static __inline unsigned ieee754_getrm(void)
-{
-	return (ieee754_csr.rm);
-}
-static __inline unsigned ieee754_setrm(unsigned rm)
-{
-	return (ieee754_csr.rm = rm);
-}
-
-/*
- * get current exceptions
- */
-static __inline unsigned ieee754_getcx(void)
-{
-	return (ieee754_csr.cx);
-}
-
-/* test for current exception condition 
- */
-static __inline int ieee754_cxtest(unsigned n)
-{
-	return (ieee754_csr.cx & n);
-}
-
-/*
- * get sticky exceptions
- */
-static __inline unsigned ieee754_getsx(void)
-{
-	return (ieee754_csr.sx);
-}
-
-/* clear sticky conditions
-*/
-static __inline unsigned ieee754_clrsx(void)
-{
-	return (ieee754_csr.sx = 0);
-}
-
-/* test for sticky exception condition 
- */
-static __inline int ieee754_sxtest(unsigned n)
-{
-	return (ieee754_csr.sx & n);
-}
-
-/* debugging */
-ieee754sp ieee754sp_dump(char *s, ieee754sp x);
-ieee754dp ieee754dp_dump(char *s, ieee754dp x);
-
-#define IEEE754_SPCVAL_PZERO	0
-#define IEEE754_SPCVAL_NZERO	1
-#define IEEE754_SPCVAL_PONE	2
-#define IEEE754_SPCVAL_NONE	3
-#define IEEE754_SPCVAL_PTEN	4
-#define IEEE754_SPCVAL_NTEN	5
-#define IEEE754_SPCVAL_PINFINITY	6
-#define IEEE754_SPCVAL_NINFINITY	7
-#define IEEE754_SPCVAL_INDEF	8
-#define IEEE754_SPCVAL_PMAX	9	/* +max norm */
-#define IEEE754_SPCVAL_NMAX	10	/* -max norm */
-#define IEEE754_SPCVAL_PMIN	11	/* +min norm */
-#define IEEE754_SPCVAL_NMIN	12	/* +min norm */
-#define IEEE754_SPCVAL_PMIND	13	/* +min denorm */
-#define IEEE754_SPCVAL_NMIND	14	/* +min denorm */
-#define IEEE754_SPCVAL_P1E31	15	/* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63	16	/* + 1.0e63 */
-
-extern const struct ieee754dp_konst __ieee754dp_spcvals[];
-extern const struct ieee754sp_konst __ieee754sp_spcvals[];
-#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
-#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
-
-/* return infinity with given sign
-*/
-#define ieee754dp_inf(sn)	\
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754dp_zero(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754dp_one(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754dp_ten(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754dp_indef() \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754dp_max(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754dp_min(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754dp_mind(sn) \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754dp_1e31() \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754dp_1e63() \
-  (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
-
-#define ieee754sp_inf(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
-#define ieee754sp_zero(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
-#define ieee754sp_one(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
-#define ieee754sp_ten(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
-#define ieee754sp_indef() \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
-#define ieee754sp_max(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
-#define ieee754sp_min(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
-#define ieee754sp_mind(sn) \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
-#define ieee754sp_1e31() \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
-#define ieee754sp_1e63() \
-  (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
-
-/* indefinite integer value 
-*/
-#define ieee754si_indef()	INT_MIN
-#ifdef LONG_LONG_MIN
-#define ieee754di_indef()	LONG_LONG_MIN
-#else
-#define ieee754di_indef()	(-9223372036854775807LL-1)
-#endif
-
-/* IEEE exception context, passed to handler */
-struct ieee754xctx {
-	const char *op;		/* operation name */
-	int rt;			/* result type */
-	union {
-		ieee754sp sp;	/* single precision */
-		ieee754dp dp;	/* double precision */
-#ifdef IEEE854_XP
-		ieee754xp xp;	/* extended precision */
-#endif
-		int si;		/* standard signed integer (32bits) */
-		long long di;	/* extended signed integer (64bits) */
-	} rv;			/* default result format implied by op */
-	va_list ap;
-};
-
-/* result types for xctx.rt */
-#define IEEE754_RT_SP	0
-#define IEEE754_RT_DP	1
-#define IEEE754_RT_XP	2
-#define IEEE754_RT_SI	3
-#define IEEE754_RT_DI	4
-
-extern void ieee754_xcpt(struct ieee754xctx *xcp);
-
-/* compat */
-#define ieee754dp_fix(x)	ieee754dp_tint(x)
-#define ieee754sp_fix(x)	ieee754sp_tint(x)
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754d.c linux-2.4.20-pre7/arch/mips64/math-emu/ieee754d.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754d.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754d.c	Wed Dec 31 16:00:00 1969
@@ -1,142 +0,0 @@
-/* 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.
- *
- *  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.
- *
- * ########################################################################
- */
-
-/**************************************************************************
- *  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 "ieee754.h"
-
-#define DP_EBIAS	1023
-#define DP_EMIN		(-1022)
-#define DP_EMAX		1023
-#define DP_FBITS	52
-
-#define SP_EBIAS	127
-#define SP_EMIN		(-126)
-#define SP_EMAX		127
-#define SP_FBITS	23
-
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
-#define DP_HIDDEN_BIT	DP_MBIT(DP_FBITS)
-#define DP_SIGN_BIT	DP_MBIT(63)
-
-
-#define SP_MBIT(x)	((unsigned long)1 << (x))
-#define SP_HIDDEN_BIT	SP_MBIT(SP_FBITS)
-#define SP_SIGN_BIT	SP_MBIT(31)
-
-
-#define SPSIGN(sp)	(sp.parts.sign)
-#define SPBEXP(sp)	(sp.parts.bexp)
-#define SPMANT(sp)	(sp.parts.mant)
-
-#define DPSIGN(dp)	(dp.parts.sign)
-#define DPBEXP(dp)	(dp.parts.bexp)
-#define DPMANT(dp)	(dp.parts.mant)
-
-ieee754dp ieee754dp_dump(char *m, ieee754dp x)
-{
-	int i;
-
-	printk("%s", m);
-	printk("<%08x,%08x>\n", (unsigned) (x.bits >> 32),
-	       (unsigned) x.bits);
-	printk("\t=");
-	switch (ieee754dp_class(x)) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		printk("Nan %c", DPSIGN(x) ? '-' : '+');
-		for (i = DP_FBITS - 1; i >= 0; i--)
-			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
-		break;
-	case IEEE754_CLASS_INF:
-		printk("%cInfinity", DPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_ZERO:
-		printk("%cZero", DPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_DNORM:
-		printk("%c0.", DPSIGN(x) ? '-' : '+');
-		for (i = DP_FBITS - 1; i >= 0; i--)
-			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
-		printk("e%d", DPBEXP(x) - DP_EBIAS);
-		break;
-	case IEEE754_CLASS_NORM:
-		printk("%c1.", DPSIGN(x) ? '-' : '+');
-		for (i = DP_FBITS - 1; i >= 0; i--)
-			printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
-		printk("e%d", DPBEXP(x) - DP_EBIAS);
-		break;
-	default:
-		printk("Illegal/Unknown IEEE754 value class");
-	}
-	printk("\n");
-	return x;
-}
-
-ieee754sp ieee754sp_dump(char *m, ieee754sp x)
-{
-	int i;
-
-	printk("%s=", m);
-	printk("<%08x>\n", (unsigned) x.bits);
-	printk("\t=");
-	switch (ieee754sp_class(x)) {
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_SNAN:
-		printk("Nan %c", SPSIGN(x) ? '-' : '+');
-		for (i = SP_FBITS - 1; i >= 0; i--)
-			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
-		break;
-	case IEEE754_CLASS_INF:
-		printk("%cInfinity", SPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_ZERO:
-		printk("%cZero", SPSIGN(x) ? '-' : '+');
-		break;
-	case IEEE754_CLASS_DNORM:
-		printk("%c0.", SPSIGN(x) ? '-' : '+');
-		for (i = SP_FBITS - 1; i >= 0; i--)
-			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
-		printk("e%d", SPBEXP(x) - SP_EBIAS);
-		break;
-	case IEEE754_CLASS_NORM:
-		printk("%c1.", SPSIGN(x) ? '-' : '+');
-		for (i = SP_FBITS - 1; i >= 0; i--)
-			printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
-		printk("e%d", SPBEXP(x) - SP_EBIAS);
-		break;
-	default:
-		printk("Illegal/Unknown IEEE754 value class");
-	}
-	printk("\n");
-	return x;
-}
-
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754dp.c linux-2.4.20-pre7/arch/mips64/math-emu/ieee754dp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754dp.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754dp.c	Wed Dec 31 16:00:00 1969
@@ -1,197 +0,0 @@
-/* IEEE754 floating point arithmetic
- * double precision: common utilities
- */
-/*
- * 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.
- *
- *  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 "ieee754dp.h"
-
-int ieee754dp_class(ieee754dp x)
-{
-	COMPXDP;
-	EXPLODEXDP;
-	return xc;
-}
-
-int ieee754dp_isnan(ieee754dp x)
-{
-	return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
-}
-
-int ieee754dp_issnan(ieee754dp x)
-{
-	assert(ieee754dp_isnan(x));
-	if (ieee754_csr.noq)
-		return 1;
-	return !(DPMANT(x) & DP_MBIT(DP_MBITS - 1));
-}
-
-
-ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-	if (!TSTX())
-		return r;
-
-	ax.op = op;
-	ax.rt = IEEE754_RT_DP;
-	ax.rv.dp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.dp;
-}
-
-ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	assert(ieee754dp_isnan(r));
-
-	if (!ieee754dp_issnan(r))	/* QNAN does not cause invalid op !! */
-		return r;
-
-	if (!SETCX(IEEE754_INVALID_OPERATION)) {
-		/* not enabled convert to a quiet NaN */
-		if (ieee754_csr.noq)
-			return r;
-		DPMANT(r) |= DP_MBIT(DP_MBITS - 1);
-		return r;
-	}
-
-	ax.op = op;
-	ax.rt = 0;
-	ax.rv.dp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.dp;
-}
-
-ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y)
-{
-	assert(ieee754dp_isnan(x));
-	assert(ieee754dp_isnan(y));
-
-	if (DPMANT(x) > DPMANT(y))
-		return x;
-	else
-		return y;
-}
-
-
-/* generate a normal/denormal number with over,under handeling
- * sn is sign
- * xe is an unbiased exponent
- * xm is 3bit extended precision value.
- */
-ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm)
-{
-	assert(xm);		/* we dont gen exact zeros (probably should) */
-
-	assert((xm >> (DP_MBITS + 1 + 3)) == 0);	/* no execess */
-	assert(xm & (DP_HIDDEN_BIT << 3));
-
-	if (xe < DP_EMIN) {
-		/* strip lower bits */
-		int es = DP_EMIN - xe;
-
-		if (ieee754_csr.nod) {
-			SETCX(IEEE754_UNDERFLOW);
-			return ieee754dp_zero(sn);
-		}
-
-		/* 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);
-		/* 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;
-		}
-		/* adjust exponent for rounding add overflowing 
-		 */
-		if (xm >> (DP_MBITS + 3 + 1)) {	/* add causes mantissa overflow */
-			xm >>= 1;
-			xe++;
-		}
-	}
-	/* strip grs bits */
-	xm >>= 3;
-
-	assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
-	assert(xe >= DP_EMIN);
-
-	if (xe > DP_EMAX) {
-		SETCX(IEEE754_OVERFLOW);
-		/* -O can be table indexed by (rm,sn) */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RN:
-			return ieee754dp_inf(sn);
-		case IEEE754_RZ:
-			return ieee754dp_max(sn);
-		case IEEE754_RU:	/* toward +Infinity */
-			if (sn == 0)
-				return ieee754dp_inf(0);
-			else
-				return ieee754dp_max(1);
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn == 0)
-				return ieee754dp_max(0);
-			else
-				return ieee754dp_inf(1);
-		}
-	}
-	/* gen norm/denorm/zero */
-
-	if ((xm & DP_HIDDEN_BIT) == 0) {
-		/* we underflow (tiny/zero) */
-		assert(xe == DP_EMIN);
-		SETCX(IEEE754_UNDERFLOW);
-		return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
-	} else {
-		assert((xm >> (DP_MBITS + 1)) == 0);	/* no execess */
-		assert(xm & DP_HIDDEN_BIT);
-
-		return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754dp.h linux-2.4.20-pre7/arch/mips64/math-emu/ieee754dp.h
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754dp.h	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754dp.h	Wed Dec 31 16:00:00 1969
@@ -1,83 +0,0 @@
-/* 
- * IEEE754 floating point
- * double precision internal header file
- */
-/*
- * 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.
- *
- *  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 "ieee754int.h"
-
-#define assert(expr) ((void)0)
-
-/* 3bit extended double precision sticky right shift */
-#define XDPSRS(v,rs)	\
-  ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
-
-#define XDPSRSX1() \
-  (xe++, (xm = (xm >> 1) | (xm & 1)))
-
-#define XDPSRS1(v)	\
-  (((v) >> 1) | ((v) & 1))
-
-/* convert denormal to normalized with extended exponent */
-#define DPDNORMx(m,e) \
-  while( (m >> DP_MBITS) == 0) { m <<= 1; e--; }
-#define DPDNORMX	DPDNORMx(xm,xe)
-#define DPDNORMY	DPDNORMx(ym,ye)
-
-static __inline ieee754dp builddp(int s, int bx, unsigned long long m)
-{
-	ieee754dp r;
-
-	assert((s) == 0 || (s) == 1);
-	assert((bx) >= DP_EMIN - 1 + DP_EBIAS
-	       && (bx) <= DP_EMAX + 1 + DP_EBIAS);
-	assert(((m) >> DP_MBITS) == 0);
-
-	r.parts.sign = s;
-	r.parts.bexp = bx;
-	r.parts.mant = m;
-	return r;
-}
-
-extern int ieee754dp_isnan(ieee754dp);
-extern int ieee754dp_issnan(ieee754dp);
-extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
-extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
-extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
-extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
-extern ieee754dp ieee754dp_format(int, int, unsigned long long);
-
-
-#define DPNORMRET2(s,e,m,name,a0,a1) \
-{ \
-    ieee754dp V = ieee754dp_format(s,e,m); \
-    if(TSTX()) \
-      return ieee754dp_xcpt(V,name,a0,a1); \
-    else \
-      return V; \
-}
-
-#define DPNORMRET1(s,e,m,name,a0)  DPNORMRET2(s,e,m,name,a0,a0)
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754int.h linux-2.4.20-pre7/arch/mips64/math-emu/ieee754int.h
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754int.h	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754int.h	Wed Dec 31 16:00:00 1969
@@ -1,135 +0,0 @@
-/* 
- * IEEE754 floating point
- * common internal header file
- */
-/*
- * 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.
- *
- *  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 "ieee754.h"
-
-#define DP_EBIAS	1023
-#define DP_EMIN		(-1022)
-#define DP_EMAX		1023
-#define DP_MBITS	52
-
-#define SP_EBIAS	127
-#define SP_EMIN		(-126)
-#define SP_EMAX		127
-#define SP_MBITS	23
-
-#define DP_MBIT(x)	((unsigned long long)1 << (x))
-#define DP_HIDDEN_BIT	DP_MBIT(DP_MBITS)
-#define DP_SIGN_BIT	DP_MBIT(63)
-
-#define SP_MBIT(x)	((unsigned long)1 << (x))
-#define SP_HIDDEN_BIT	SP_MBIT(SP_MBITS)
-#define SP_SIGN_BIT	SP_MBIT(31)
-
-
-#define SPSIGN(sp)	(sp.parts.sign)
-#define SPBEXP(sp)	(sp.parts.bexp)
-#define SPMANT(sp)	(sp.parts.mant)
-
-#define DPSIGN(dp)	(dp.parts.sign)
-#define DPBEXP(dp)	(dp.parts.bexp)
-#define DPMANT(dp)	(dp.parts.mant)
-
-#define CLPAIR(x,y)	((x)*6+(y))
-
-#define CLEARCX	\
-  (ieee754_csr.cx = 0)
-
-#define SETCX(x) \
-  (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x),ieee754_csr.mx & (x))
-
-#define TSTX()	\
-	(ieee754_csr.cx & ieee754_csr.mx)
-
-
-#define COMPXSP \
-  unsigned xm; int xe; int xs; int xc
-
-#define COMPYSP \
-  unsigned ym; int ye; int ys; int yc
-
-#define EXPLODESP(v,vc,vs,ve,vm) \
-{\
-    vs = SPSIGN(v);\
-    ve = SPBEXP(v);\
-    vm = SPMANT(v);\
-    if(ve == SP_EMAX+1+SP_EBIAS){\
-	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 if(ve == SP_EMIN-1+SP_EBIAS) {\
-	if(vm) {\
-	    ve = SP_EMIN;\
-	    vc = IEEE754_CLASS_DNORM;\
-	} else\
-	  vc = IEEE754_CLASS_ZERO;\
-    } else {\
-	ve -= SP_EBIAS;\
-	vm |= SP_HIDDEN_BIT;\
-	vc = IEEE754_CLASS_NORM;\
-    }\
-}
-#define EXPLODEXSP EXPLODESP(x,xc,xs,xe,xm)
-#define EXPLODEYSP EXPLODESP(y,yc,ys,ye,ym)
-
-
-#define COMPXDP \
-unsigned long long xm; int xe; int xs; int xc
-
-#define COMPYDP \
-unsigned long long ym; int ye; int ys; int yc
-
-#define EXPLODEDP(v,vc,vs,ve,vm) \
-{\
-    vm = DPMANT(v);\
-    vs = DPSIGN(v);\
-    ve = DPBEXP(v);\
-    if(ve == DP_EMAX+1+DP_EBIAS){\
-	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 if(ve == DP_EMIN-1+DP_EBIAS) {\
-	if(vm) {\
-	    ve = DP_EMIN;\
-	    vc = IEEE754_CLASS_DNORM;\
-	} else\
-	  vc = IEEE754_CLASS_ZERO;\
-    } else {\
-	ve -= DP_EBIAS;\
-	vm |= DP_HIDDEN_BIT;\
-	vc = IEEE754_CLASS_NORM;\
-    }\
-}
-#define EXPLODEXDP EXPLODEDP(x,xc,xs,xe,xm)
-#define EXPLODEYDP EXPLODEDP(y,yc,ys,ye,ym)
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754m.c linux-2.4.20-pre7/arch/mips64/math-emu/ieee754m.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754m.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754m.c	Wed Dec 31 16:00:00 1969
@@ -1,56 +0,0 @@
-/*
- * floor, trunc, ceil
- */
-/*
- * 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.
- *
- *  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 "ieee754.h"
-
-ieee754dp ieee754dp_floor(ieee754dp x)
-{
-	ieee754dp i;
-
-	if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
-		return ieee754dp_sub(i, ieee754dp_one(0));
-	else
-		return i;
-}
-
-ieee754dp ieee754dp_ceil(ieee754dp x)
-{
-	ieee754dp i;
-
-	if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
-		return ieee754dp_add(i, ieee754dp_one(0));
-	else
-		return i;
-}
-
-ieee754dp ieee754dp_trunc(ieee754dp x)
-{
-	ieee754dp i;
-
-	(void) ieee754dp_modf(x, &i);
-	return i;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754sp.c linux-2.4.20-pre7/arch/mips64/math-emu/ieee754sp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754sp.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754sp.c	Wed Dec 31 16:00:00 1969
@@ -1,197 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-int ieee754sp_class(ieee754sp x)
-{
-	COMPXSP;
-	EXPLODEXSP;
-	return xc;
-}
-
-int ieee754sp_isnan(ieee754sp x)
-{
-	return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
-}
-
-int ieee754sp_issnan(ieee754sp x)
-{
-	assert(ieee754sp_isnan(x));
-	if (ieee754_csr.noq)
-		return 1;
-	return !(SPMANT(x) & SP_MBIT(SP_MBITS - 1));
-}
-
-
-ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	if (!TSTX())
-		return r;
-
-	ax.op = op;
-	ax.rt = IEEE754_RT_SP;
-	ax.rv.sp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.sp;
-}
-
-ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
-{
-	struct ieee754xctx ax;
-
-	assert(ieee754sp_isnan(r));
-
-	if (!ieee754sp_issnan(r))	/* QNAN does not cause invalid op !! */
-		return r;
-
-	if (!SETCX(IEEE754_INVALID_OPERATION)) {
-		/* not enabled convert to a quiet NaN */
-		if (ieee754_csr.noq)
-			return r;
-		SPMANT(r) |= SP_MBIT(SP_MBITS - 1);
-		return r;
-	}
-
-	ax.op = op;
-	ax.rt = 0;
-	ax.rv.sp = r;
-	va_start(ax.ap, op);
-	ieee754_xcpt(&ax);
-	return ax.rv.sp;
-}
-
-ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y)
-{
-	assert(ieee754sp_isnan(x));
-	assert(ieee754sp_isnan(y));
-
-	if (SPMANT(x) > SPMANT(y))
-		return x;
-	else
-		return y;
-}
-
-
-/* generate a normal/denormal number with over,under handeling
- * sn is sign
- * xe is an unbiased exponent
- * xm is 3bit extended precision value.
- */
-ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
-{
-	assert(xm);		/* we dont gen exact zeros (probably should) */
-
-	assert((xm >> (SP_MBITS + 1 + 3)) == 0);	/* no execess */
-	assert(xm & (SP_HIDDEN_BIT << 3));
-
-	if (xe < SP_EMIN) {
-		/* strip lower bits */
-		int es = SP_EMIN - xe;
-
-		if (ieee754_csr.nod) {
-			SETCX(IEEE754_UNDERFLOW);
-			return ieee754sp_zero(sn);
-		}
-
-		/* 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);
-		/* 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;
-		}
-		/* adjust exponent for rounding add overflowing 
-		 */
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* add causes mantissa overflow */
-			xm >>= 1;
-			xe++;
-		}
-	}
-	/* strip grs bits */
-	xm >>= 3;
-
-	assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
-	assert(xe >= SP_EMIN);
-
-	if (xe > SP_EMAX) {
-		SETCX(IEEE754_OVERFLOW);
-		/* -O can be table indexed by (rm,sn) */
-		switch (ieee754_csr.rm) {
-		case IEEE754_RN:
-			return ieee754sp_inf(sn);
-		case IEEE754_RZ:
-			return ieee754sp_max(sn);
-		case IEEE754_RU:	/* toward +Infinity */
-			if (sn == 0)
-				return ieee754sp_inf(0);
-			else
-				return ieee754sp_max(1);
-		case IEEE754_RD:	/* toward -Infinity */
-			if (sn == 0)
-				return ieee754sp_max(0);
-			else
-				return ieee754sp_inf(1);
-		}
-	}
-	/* gen norm/denorm/zero */
-
-	if ((xm & SP_HIDDEN_BIT) == 0) {
-		/* we underflow (tiny/zero) */
-		assert(xe == SP_EMIN);
-		SETCX(IEEE754_UNDERFLOW);
-		return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
-	} else {
-		assert((xm >> (SP_MBITS + 1)) == 0);	/* no execess */
-		assert(xm & SP_HIDDEN_BIT);
-
-		return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754sp.h linux-2.4.20-pre7/arch/mips64/math-emu/ieee754sp.h
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754sp.h	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754sp.h	Wed Dec 31 16:00:00 1969
@@ -1,89 +0,0 @@
-/* 
- * IEEE754 floating point
- * double precision internal header file
- */
-/*
- * 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.
- *
- *  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 "ieee754int.h"
-
-#define assert(expr) ((void)0)
-
-/* 3bit extended single precision sticky right shift */
-#define SPXSRSXn(rs) \
-  (xe += rs, \
-   xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
-
-#define SPXSRSX1() \
-  (xe++, (xm = (xm >> 1) | (xm & 1)))
-
-#define SPXSRSYn(rs) \
-   (ye+=rs, \
-    ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
-
-#define SPXSRSY1() \
-   (ye++, (ym = (ym >> 1) | (ym & 1)))
-
-/* convert denormal to normalized with extended exponent */
-#define SPDNORMx(m,e) \
-  while( (m >> SP_MBITS) == 0) { m <<= 1; e--; }
-#define SPDNORMX	SPDNORMx(xm,xe)
-#define SPDNORMY	SPDNORMx(ym,ye)
-
-static __inline ieee754sp buildsp(int s, int bx, unsigned m)
-{
-	ieee754sp r;
-
-	assert((s) == 0 || (s) == 1);
-	assert((bx) >= SP_EMIN - 1 + SP_EBIAS
-	       && (bx) <= SP_EMAX + 1 + SP_EBIAS);
-	assert(((m) >> SP_MBITS) == 0);
-
-	r.parts.sign = s;
-	r.parts.bexp = bx;
-	r.parts.mant = m;
-
-	return r;
-}
-
-extern int ieee754sp_isnan(ieee754sp);
-extern int ieee754sp_issnan(ieee754sp);
-extern int ieee754si_xcpt(int, const char *, ...);
-extern long long ieee754di_xcpt(long long, const char *, ...);
-extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
-extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
-extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
-extern ieee754sp ieee754sp_format(int, int, unsigned);
-
-
-#define SPNORMRET2(s,e,m,name,a0,a1) \
-{ \
-    ieee754sp V = ieee754sp_format(s,e,m); \
-    if(TSTX()) \
-      return ieee754sp_xcpt(V,name,a0,a1); \
-    else \
-      return V; \
-}
-
-#define SPNORMRET1(s,e,m,name,a0)  SPNORMRET2(s,e,m,name,a0,a0)
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/ieee754xcpt.c linux-2.4.20-pre7/arch/mips64/math-emu/ieee754xcpt.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/ieee754xcpt.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/ieee754xcpt.c	Wed Dec 31 16:00:00 1969
@@ -1,48 +0,0 @@
-/*
- * 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.
- *
- *  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.
- *
- * ########################################################################
- */
-
-/**************************************************************************
- *  Nov 7, 2000
- *  Added preprocessor hacks to map to Linux kernel diagnostics. 
- *
- *  Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
- *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *************************************************************************/
-
-#include "ieee754.h"
-
-/*
- * Very naff exception handler (you can plug in your own and
- * override this).
- */
-
-static const char *const rtnames[] = {
-	"sp", "dp", "xp", "si", "di"
-};
-
-void ieee754_xcpt(struct ieee754xctx *xcp)
-{
-	printk("floating point exception in \"%s\", type=%s\n",
-		xcp->op, rtnames[xcp->rt]);
-}
-
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/kernel_linkage.c linux-2.4.20-pre7/arch/mips64/math-emu/kernel_linkage.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/kernel_linkage.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/kernel_linkage.c	Wed Dec 31 16:00:00 1969
@@ -1,95 +0,0 @@
-/**************************************************************************
- *
- *  arch/mips/math_emu/kernel_linkage.c
- *
- *  Kevin D. Kissell, kevink@mips 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.
- *
- *************************************************************************/
-/*
- * 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>
-#include <asm/uaccess.h>
-
-#include <asm/fpu_emulator.h>
-
-extern struct mips_fpu_emulator_private fpuemuprivate;
-
-#define SIGNALLING_NAN 0x7ff800007ff80000LL
-
-void fpu_emulator_init_fpu(void)
-{
-	static int first = 1;
-	int i;
- 
-	if (first) {
-		first = 0;
-		printk("Algorithmics/MIPS FPU Emulator v1.4\n");
-	}
-
-	current->thread.fpu.soft.sr = 0;
-	for (i = 0; i < 32; i++) {
-		current->thread.fpu.soft.regs[i] = SIGNALLING_NAN;
-	}
-}
-
-
-/*
- * Emulator context save/restore to/from a signal context
- * presumed to be on the user stack, and therefore accessed
- * with appropriate macros from uaccess.h
- */
-
-int fpu_emulator_save_context(struct sigcontext *sc)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0; i < 32; i++) {
-		err |=
-		    __put_user(current->thread.fpu.soft.regs[i],
-			       &sc->sc_fpregs[i]);
-	}
-	err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
-	err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
-
-	return err;
-}
-
-int fpu_emulator_restore_context(struct sigcontext *sc)
-{
-	int i;
-	int err = 0;
-
-	for (i = 0; i < 32; i++) {
-		err |=
-		    __get_user(current->thread.fpu.soft.regs[i],
-			       &sc->sc_fpregs[i]);
-	}
-	err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr);
-	err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir);
-
-	return err;
-}
-
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_add.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_add.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_add.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_add.c	Wed Dec 31 16:00:00 1969
@@ -1,180 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y)
-{
-	COMPXSP;
-	COMPYSP;
-
-	EXPLODEXSP;
-	EXPLODEYSP;
-
-	CLEARCX;
-
-	switch (CLPAIR(xc, yc)) {
-	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
-		return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "add", x,
-					 y);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs == ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs == ys)
-			return x;
-		else
-			return ieee754sp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-	/* provide guard,round and stick bit space */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		SPXSRSYn(s);
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		SPXSRSXn(s);
-	}
-	assert(xe == ye);
-	assert(xe <= SP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 * leaving result in xm,xs,xe
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* carry out */
-			SPXSRSX1();
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0)
-			return ieee754sp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-		/* normalize in extended single precision */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-
-	}
-	SPNORMRET2(xs, xe, xm, "add", x, y);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_cmp.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_cmp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_cmp.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_cmp.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp)
-{
-	CLEARCX;
-
-	if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
-		if (cmp & IEEE754_CUN)
-			return 1;
-		if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-			if (SETCX(IEEE754_INVALID_OPERATION))
-				return ieee754si_xcpt(0, "fcmpf", x);
-		}
-		return 0;
-	} else {
-		int vx = x.bits;
-		int vy = y.bits;
-
-		if (vx < 0)
-			vx = -vx ^ SP_SIGN_BIT;
-		if (vy < 0)
-			vy = -vy ^ SP_SIGN_BIT;
-
-		if (vx < vy)
-			return (cmp & IEEE754_CLT) != 0;
-		else if (vx == vy)
-			return (cmp & IEEE754_CEQ) != 0;
-		else
-			return (cmp & IEEE754_CGT) != 0;
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_div.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_div.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_div.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_div.c	Wed Dec 31 16:00:00 1969
@@ -1,160 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y)
-{
-	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);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-		return ieee754sp_zero(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return ieee754sp_inf(xs ^ ys);
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		SETCX(IEEE754_ZERO_DIVIDE);
-		return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		return ieee754sp_zero(xs == ys ? 0 : 1);
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-	/* provide rounding space */
-	xm <<= 3;
-	ym <<= 3;
-
-	{
-		/* now the dirty work */
-
-		unsigned rm = 0;
-		int re = xe - ye;
-		unsigned bm;
-
-		for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) {
-			if (xm >= ym) {
-				xm -= ym;
-				rm |= bm;
-				if (xm == 0)
-					break;
-			}
-			xm <<= 1;
-		}
-		rm <<= 1;
-		if (xm)
-			rm |= 1;	/* have remainder, set sticky */
-
-		assert(rm);
-
-		/* normalise rm to rounding precision ?
-		 */
-		while ((rm >> (SP_MBITS + 3)) == 0) {
-			rm <<= 1;
-			re--;
-		}
-
-		SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_fdp.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_fdp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_fdp.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_fdp.c	Wed Dec 31 16:00:00 1969
@@ -1,69 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_fdp(ieee754dp x)
-{
-	COMPXDP;
-
-	CLEARCX;
-
-	EXPLODEXDP;
-
-	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);
-	case IEEE754_CLASS_INF:
-		return ieee754sp_inf(xs);
-	case IEEE754_CLASS_ZERO:
-		return ieee754sp_zero(xs);
-	case IEEE754_CLASS_DNORM:
-		/* cant possibly be sp representable */
-		SETCX(IEEE754_UNDERFLOW);
-		return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-
-	{
-		unsigned long rm;
-
-		/* convert from DP_MBITS to SP_MBITS+3 with sticky right shift 
-		 */
-		rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
-		    ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
-
-		SPNORMRET1(xs, xe, rm, "fdp", x);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_fint.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_fint.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_fint.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_fint.c	Wed Dec 31 16:00:00 1969
@@ -1,78 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_fint(int x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754sp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754sp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754sp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1 << 31))
-			xm = ((unsigned) 1 << 31);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-	xe = SP_MBITS + 3;
-
-	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
-		 */
-		while (xm >> (SP_MBITS + 1 + 3)) {
-			SPXSRSX1();
-		}
-	} else {
-		/* normalize in grs extended single precision 
-		 */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	SPNORMRET1(xs, xe, xm, "fint", x);
-}
-
-
-ieee754sp ieee754sp_funs(unsigned int u)
-{
-	if ((int) u < 0)
-		return ieee754sp_add(ieee754sp_1e31(),
-				     ieee754sp_fint(u & ~(1 << 31)));
-	return ieee754sp_fint(u);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_flong.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_flong.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_flong.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_flong.c	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_flong(long long x)
-{
-	COMPXDP;		/* <--- need 64-bit mantissa temp */
-
-	CLEARCX;
-
-	if (x == 0)
-		return ieee754sp_zero(0);
-	if (x == 1 || x == -1)
-		return ieee754sp_one(x < 0);
-	if (x == 10 || x == -10)
-		return ieee754sp_ten(x < 0);
-
-	xs = (x < 0);
-	if (xs) {
-		if (x == (1ULL << 63))
-			xm = (1ULL << 63);	/* max neg can't be safely negated */
-		else
-			xm = -x;
-	} else {
-		xm = x;
-	}
-	xe = SP_MBITS + 3;
-
-	if (xm >> (SP_MBITS + 1 + 3)) {
-		/* shunt out overflow bits 
-		 */
-		while (xm >> (SP_MBITS + 1 + 3)) {
-			SPXSRSX1();
-		}
-	} else {
-		/* normalize in grs extended single precision */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	SPNORMRET1(xs, xe, xm, "sp_flong", x);
-}
-
-
-ieee754sp ieee754sp_fulong(unsigned long long u)
-{
-	if ((long long) u < 0)
-		return ieee754sp_add(ieee754sp_1e63(),
-				     ieee754sp_flong(u & ~(1ULL << 63)));
-	return ieee754sp_flong(u);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_frexp.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_frexp.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_frexp.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_frexp.c	Wed Dec 31 16:00:00 1969
@@ -1,53 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-/* close to ieeep754sp_logb 
-*/
-ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
-{
-	COMPXSP;
-	CLEARCX;
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*eptr = 0;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		SPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	*eptr = xe + 1;
-	return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_logb.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_logb.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_logb.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_logb.c	Wed Dec 31 16:00:00 1969
@@ -1,54 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_logb(ieee754sp x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(x, "logb", x);
-	case IEEE754_CLASS_QNAN:
-		return x;
-	case IEEE754_CLASS_INF:
-		return ieee754sp_inf(0);
-	case IEEE754_CLASS_ZERO:
-		return ieee754sp_inf(1);
-	case IEEE754_CLASS_DNORM:
-		SPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	return ieee754sp_fint(xe);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_modf.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_modf.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_modf.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_modf.c	Wed Dec 31 16:00:00 1969
@@ -1,80 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-/* modf function is always exact for a finite number
-*/
-ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		*ip = x;
-		return x;
-	case IEEE754_CLASS_DNORM:
-		/* far to small */
-		*ip = ieee754sp_zero(xs);
-		return x;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	if (xe < 0) {
-		*ip = ieee754sp_zero(xs);
-		return x;
-	}
-	if (xe >= SP_MBITS) {
-		*ip = x;
-		return ieee754sp_zero(xs);
-	}
-	/* generate ipart mantissa by clearing bottom bits 
-	 */
-	*ip = buildsp(xs, xe + SP_EBIAS,
-		      ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
-		      ~SP_HIDDEN_BIT);
-
-	/* generate fpart mantissa by clearing top bits
-	 * and normalizing (must be able to normalize)
-	 */
-	xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe));
-	if (xm == 0)
-		return ieee754sp_zero(xs);
-
-	while ((xm >> SP_MBITS) == 0) {
-		xm <<= 1;
-		xe--;
-	}
-	return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_mul.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_mul.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_mul.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_mul.c	Wed Dec 31 16:00:00 1969
@@ -1,174 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y)
-{
-	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);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Infinity handeling */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		return ieee754sp_inf(xs ^ ys);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return ieee754sp_zero(xs ^ ys);
-
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* rm = xm * ym, re = xe+ye basicly */
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-	{
-		int re = xe + ye;
-		int rs = xs ^ ys;
-		unsigned rm;
-
-		/* shunt to top of word */
-		xm <<= 32 - (SP_MBITS + 1);
-		ym <<= 32 - (SP_MBITS + 1);
-
-		/* multiply 32bits xm,ym to give high 32bits rm with stickness
-		 */
-		{
-			unsigned short lxm = xm & 0xffff;
-			unsigned short hxm = xm >> 16;
-			unsigned short lym = ym & 0xffff;
-			unsigned short hym = ym >> 16;
-			unsigned lrm;
-			unsigned hrm;
-
-			lrm = lxm * lym;	/* 16 * 16 => 32 */
-			hrm = hxm * hym;	/* 16 * 16 => 32 */
-
-			{
-				unsigned t = lxm * hym;	/* 16 * 16 => 32 */
-				{
-					unsigned at = lrm + (t << 16);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 16);
-			}
-
-			{
-				unsigned t = hxm * lym;	/* 16 * 16 => 32 */
-				{
-					unsigned at = lrm + (t << 16);
-					hrm += at < lrm;
-					lrm = at;
-				}
-				hrm = hrm + (t >> 16);
-			}
-			rm = hrm | (lrm != 0);
-		}
-
-		/*
-		 * sticky shift down to normal rounding precision
-		 */
-		if ((int) rm < 0) {
-			rm = (rm >> (32 - (SP_MBITS + 1 + 3))) |
-			    ((rm << (SP_MBITS + 1 + 3)) != 0);
-			re++;
-		} else {
-			rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) |
-			    ((rm << (SP_MBITS + 1 + 3 + 1)) != 0);
-		}
-		assert(rm & (SP_HIDDEN_BIT << 3));
-
-		SPNORMRET2(rs, re, rm, "mul", x, y);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_scalb.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_scalb.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_scalb.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_scalb.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_scalb(ieee754sp x, int n)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	switch (xc) {
-	case IEEE754_CLASS_SNAN:
-		return ieee754sp_nanxcpt(x, "scalb", x, n);
-	case IEEE754_CLASS_QNAN:
-	case IEEE754_CLASS_INF:
-	case IEEE754_CLASS_ZERO:
-		return x;
-	case IEEE754_CLASS_DNORM:
-		SPDNORMX;
-		break;
-	case IEEE754_CLASS_NORM:
-		break;
-	}
-	SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
-}
-
-
-ieee754sp ieee754sp_ldexp(ieee754sp x, int n)
-{
-	return ieee754sp_scalb(x, n);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_simple.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_simple.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_simple.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_simple.c	Wed Dec 31 16:00:00 1969
@@ -1,66 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-int ieee754sp_finite(ieee754sp x)
-{
-	return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
-}
-
-ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y)
-{
-	CLEARCX;
-	SPSIGN(x) = SPSIGN(y);
-	return x;
-}
-
-
-ieee754sp ieee754sp_neg(ieee754sp x)
-{
-	CLEARCX;
-
-	if (ieee754sp_isnan(x))	/* but not infinity */
-		return ieee754sp_nanxcpt(x, "neg", x);
-
-	/* quick fix up */
-	SPSIGN(x) ^= 1;
-	return x;
-}
-
-
-ieee754sp ieee754sp_abs(ieee754sp x)
-{
-	CLEARCX;
-
-	if (ieee754sp_isnan(x))	/* but not infinity */
-		return ieee754sp_nanxcpt(x, "abs", x);
-
-	/* quick fix up */
-	SPSIGN(x) = 0;
-	return x;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_sqrt.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_sqrt.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_sqrt.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_sqrt.c	Wed Dec 31 16:00:00 1969
@@ -1,115 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision square root
- */
-/*
- * 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.
- *
- *  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 "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;
-
-	/* take care of Inf and NaN */
-
-	EXPLODEXDP;
-
-	/* 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_ZERO:
-		/* sqrt(0) = 0 */
-		return x;
-	case IEEE754_CLASS_INF:
-		if (xs)
-			/* sqrt(-Inf) = Nan */
-			return ieee754sp_nanxcpt(nan, "sqrt");
-		/* sqrt(+Inf) = Inf */
-		return x;
-	case IEEE754_CLASS_DNORM:
-	case IEEE754_CLASS_NORM:
-		if (xs)
-			/* sqrt(-x) = Nan */
-			return ieee754sp_nanxcpt(nan, "sqrt");
-		break;
-	}
-
-	ix = x.bits;
-
-	/* normalize x */
-	m = (ix >> 23);
-	if (m == 0) {		/* subnormal x */
-		for (i = 0; (ix & 0x00800000) == 0; i++)
-			ix <<= 1;
-		m -= i - 1;
-	}
-	m -= 127;		/* unbias exponent */
-	ix = (ix & 0x007fffff) | 0x00800000;
-	if (m & 1)		/* odd m, double x to make it even */
-		ix += ix;
-	m >>= 1;		/* m = [m/2] */
-
-	/* generate sqrt(x) bit by bit */
-	ix += ix;
-	q = s = 0;		/* q = sqrt(x) */
-	r = 0x01000000;		/* r = moving bit from right to left */
-
-	while (r != 0) {
-		t = s + r;
-		if (t <= ix) {
-			s = t + r;
-			ix -= t;
-			q += r;
-		}
-		ix += ix;
-		r >>= 1;
-	}
-
-	if (ix != 0) {
-		switch (ieee754_csr.rm) {
-		case IEEE754_RP:
-			q += 2;
-			break;
-		case IEEE754_RN:
-			q += (q & 1);
-			break;
-		}
-	}
-	ix = (q >> 1) + 0x3f000000;
-	ix += (m << 23);
-	x.bits = ix;
-	return x;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_sub.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_sub.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_sub.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_sub.c	Wed Dec 31 16:00:00 1969
@@ -1,187 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y)
-{
-	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);
-
-	case CLPAIR(IEEE754_CLASS_QNAN, 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);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
-	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
-		return x;
-
-
-		/* Inifity handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
-		if (xs != ys)
-			return x;
-		SETCX(IEEE754_INVALID_OPERATION);
-		return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y);
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
-		return ieee754sp_inf(ys ^ 1);
-
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
-		return x;
-
-		/* Zero handeling 
-		 */
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
-		if (xs != ys)
-			return x;
-		else
-			return ieee754sp_zero(ieee754_csr.rm ==
-					      IEEE754_RD);
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
-		return x;
-
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
-	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
-		/* quick fix up */
-		DPSIGN(y) ^= 1;
-		return y;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
-		SPDNORMX;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
-		SPDNORMY;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
-		SPDNORMX;
-		break;
-
-	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
-		break;
-	}
-	/* flip sign of y and handle as add */
-	ys ^= 1;
-
-	assert(xm & SP_HIDDEN_BIT);
-	assert(ym & SP_HIDDEN_BIT);
-
-
-	/* provide guard,round and stick bit space */
-	xm <<= 3;
-	ym <<= 3;
-
-	if (xe > ye) {
-		/* have to shift y fraction right to align
-		 */
-		int s = xe - ye;
-		SPXSRSYn(s);
-	} else if (ye > xe) {
-		/* have to shift x fraction right to align
-		 */
-		int s = ye - xe;
-		SPXSRSXn(s);
-	}
-	assert(xe == ye);
-	assert(xe <= SP_EMAX);
-
-	if (xs == ys) {
-		/* generate 28 bit result of adding two 27 bit numbers
-		 */
-		xm = xm + ym;
-		xe = xe;
-		xs = xs;
-
-		if (xm >> (SP_MBITS + 1 + 3)) {	/* carry out */
-			SPXSRSX1();	/* shift preserving sticky */
-		}
-	} else {
-		if (xm >= ym) {
-			xm = xm - ym;
-			xe = xe;
-			xs = xs;
-		} else {
-			xm = ym - xm;
-			xe = xe;
-			xs = ys;
-		}
-		if (xm == 0)
-			if (ieee754_csr.rm == IEEE754_RD)
-				return ieee754sp_zero(1);	/* round negative inf. => sign = -1 */
-			else
-				return ieee754sp_zero(0);	/* other round modes   => sign = 1 */
-
-		/* normalize to rounding precision 
-		 */
-		while ((xm >> (SP_MBITS + 3)) == 0) {
-			xm <<= 1;
-			xe--;
-		}
-	}
-	SPNORMRET2(xs, xe, xm, "sub", x, y);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_tint.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_tint.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_tint.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_tint.c	Wed Dec 31 16:00:00 1969
@@ -1,88 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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/kernel.h>
-#include "ieee754sp.h"
-
-int ieee754sp_tint(ieee754sp x)
-{
-	COMPXSP;
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	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);
-	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_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);
-	}
-	/* oh gawd */
-	if (xe > SP_MBITS) {
-		xm <<= xe - SP_MBITS;
-	} else if (xe < SP_MBITS) {
-		/* XXX no rounding 
-		 */
-		xm >>= SP_MBITS - xe;
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned int ieee754sp_tuns(ieee754sp x)
-{
-	ieee754sp hb = ieee754sp_1e31();
-
-	/* what if x < 0 ?? */
-	if (ieee754sp_lt(x, hb))
-		return (unsigned) ieee754sp_tint(x);
-
-	return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
-	    ((unsigned) 1 << 31);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/math-emu/sp_tlong.c linux-2.4.20-pre7/arch/mips64/math-emu/sp_tlong.c
--- linux-2.4.20-pre6/arch/mips64/math-emu/sp_tlong.c	Mon Jul  2 13:56:41 2001
+++ linux-2.4.20-pre7/arch/mips64/math-emu/sp_tlong.c	Wed Dec 31 16:00:00 1969
@@ -1,87 +0,0 @@
-/* IEEE754 floating point arithmetic
- * single precision
- */
-/*
- * 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.
- *
- *  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 "ieee754sp.h"
-
-long long ieee754sp_tlong(ieee754sp x)
-{
-	COMPXDP;		/* <-- need 64-bit mantissa tmp */
-
-	CLEARCX;
-
-	EXPLODEXSP;
-
-	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);
-		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_NORM:
-		break;
-	}
-	if (xe >= 63) {
-		SETCX(IEEE754_OVERFLOW);
-		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;
-	}
-	if (xs)
-		return -xm;
-	else
-		return xm;
-}
-
-
-unsigned long long ieee754sp_tulong(ieee754sp x)
-{
-	ieee754sp hb = ieee754sp_1e63();
-
-	/* what if x < 0 ?? */
-	if (ieee754sp_lt(x, hb))
-		return (unsigned long long) ieee754sp_tlong(x);
-
-	return (unsigned long long) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
-	    (1ULL << 63);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/mm/Makefile linux-2.4.20-pre7/arch/mips64/mm/Makefile
--- linux-2.4.20-pre6/arch/mips64/mm/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/Makefile	Thu Sep 12 20:01:40 2002
@@ -11,11 +11,15 @@
 
 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_R5000)		+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \
+				   r5k-sc.o
+obj-$(CONFIG_CPU_NEVADA)	+= r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \
+				   r5k-sc.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
+obj-$(CONFIG_CPU_MIPS64)	+= pg-mips64.o c-mips64.o tlb-r4k.o \
+				   tlbex-r4k.o tlb-glue-r4k.o
 
 #
 # Debug TLB exception handler, currently unused
@@ -24,6 +28,6 @@
 
 obj-$(CONFIG_SGI_IP22)		+= umap.o
 
-CFLAGS_tlb-glue-r4k.o := -P
+AFLAGS_tlb-glue-r4k.o := -P
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/mm/andes.c linux-2.4.20-pre7/arch/mips64/mm/andes.c
--- linux-2.4.20-pre6/arch/mips64/mm/andes.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/andes.c	Thu Sep 12 20:01:40 2002
@@ -328,7 +328,7 @@
 			printk(KERN_EMERG "Unknown L2 line size\n");
 			while(1);
 	}
-    
+
 	_update_mmu_cache = andes_update_mmu_cache;
 
         flush_cache_l1();
diff -urN linux-2.4.20-pre6/arch/mips64/mm/c-mips64.c linux-2.4.20-pre7/arch/mips64/mm/c-mips64.c
--- linux-2.4.20-pre6/arch/mips64/mm/c-mips64.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips64/mm/c-mips64.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,670 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * MIPS64 CPU variant specific Cache routines.
+ * These routine are not optimized in any way, they are done in a generic way
+ * so they can be used on all MIPS64 compliant CPUs, and also done in an
+ * attempt not to break anything for the R4xx0 style CPUs.
+ */
+#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/mips64_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 mips64_flush_cache_all_sc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache(); blast_scache();
+	__restore_flags(flags);
+}
+
+static inline void mips64_flush_cache_all_pc(void)
+{
+	unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_dcache(); blast_icache();
+	__restore_flags(flags);
+}
+
+static void
+mips64_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) {
+			mips64_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 mips64_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 mips64_flush_cache_mm_sc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips64_flush_cache_all_sc();
+	}
+}
+
+static void mips64_flush_cache_mm_pc(struct mm_struct *mm)
+{
+	if(mm->context != 0) {
+#ifdef DEBUG_CACHE
+		printk("cmm[%d]", (int)mm->context);
+#endif
+		mips64_flush_cache_all_pc();
+	}
+}
+
+static void mips64_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 mips64_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 Mips64 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 & ((unsigned long)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 mips64_flush_page_to_ram_sc(struct page *page)
+{
+	blast_scache_page((unsigned long)page_address(page));
+}
+
+static void mips64_flush_page_to_ram_pc(struct page *page)
+{
+	blast_dcache_page((unsigned long)page_address(page));
+}
+
+static void
+mips64_flush_icache_page_s(struct vm_area_struct *vma, struct page *page)
+{
+	/*
+	 * We did an scache flush therefore PI is already clean.
+	 */
+}
+
+static void
+mips64_flush_icache_range(unsigned long start, unsigned long end)
+{
+	flush_cache_all();
+}
+
+static void
+mips64_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	unsigned long address;
+
+	if (!(vma->vm_flags & VM_EXEC))
+		return;
+
+	address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & ((unsigned long)icache_size - 1));
+	blast_icache_page_indexed(address);
+}
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ */
+static void
+mips64_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= (unsigned long)dcache_size) {
+		blast_dcache();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~(dc_lsize - 1);
+		end = (addr + size) & ~((unsigned long)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
+mips64_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_scache();
+		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
+mips64_dma_cache_inv_pc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+	unsigned int flags;
+
+	if (size >= (unsigned long)dcache_size) {
+		blast_dcache();
+	} else {
+	        __save_and_cli(flags);
+		a = addr & ~((unsigned long)dc_lsize - 1);
+		end = (addr + size) & ~((unsigned long)dc_lsize - 1);
+		while (1) {
+			invalidate_dcache_line(a); /* Hit_Inv_D */
+			if (a == end) break;
+			a += (unsigned long)dc_lsize;
+		}
+		__restore_flags(flags);
+	}
+
+	bc_inv(addr, size);
+}
+
+static void
+mips64_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_scache();
+		return;
+	}
+
+	a = addr & ~(sc_lsize - 1);
+	end = (addr + size) & ~(sc_lsize - 1);
+	while (1) {
+		invalidate_scache_line(a); /* Hit_Writeback_Inv_SD */
+		if (a == end) break;
+		a += sc_lsize;
+	}
+}
+
+static void
+mips64_dma_cache_wback(unsigned long addr, unsigned long size)
+{
+	panic("mips64_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 mips64_flush_cache_sigtramp(unsigned long addr)
+{
+	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+}
+
+static void
+mips64_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 MIPS64 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 MIPS64 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"
+			     "cache 8, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 9, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (begin));
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 11, (%0)\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"
+				     "cache 7, (%0)\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 *)mips64_clear_page_dc;
+	_copy_page = (void *)mips64_copy_page_dc;
+	_flush_cache_all = mips64_flush_cache_all_pc;
+	___flush_cache_all = mips64_flush_cache_all_pc;
+	_flush_cache_mm = mips64_flush_cache_mm_pc;
+	_flush_cache_range = mips64_flush_cache_range_pc;
+	_flush_cache_page = mips64_flush_cache_page_pc;
+	_flush_page_to_ram = mips64_flush_page_to_ram_pc;
+
+	_flush_icache_page = mips64_flush_icache_page;
+
+	_dma_cache_wback_inv = mips64_dma_cache_wback_inv_pc;
+	_dma_cache_wback = mips64_dma_cache_wback;
+	_dma_cache_inv = mips64_dma_cache_inv_pc;
+}
+
+static void __init setup_scache_funcs(void)
+{
+        _flush_cache_all = mips64_flush_cache_all_sc;
+        ___flush_cache_all = mips64_flush_cache_all_sc;
+	_flush_cache_mm = mips64_flush_cache_mm_sc;
+	_flush_cache_range = mips64_flush_cache_range_sc;
+	_flush_cache_page = mips64_flush_cache_page_sc;
+	_flush_page_to_ram = mips64_flush_page_to_ram_sc;
+	_clear_page = (void *)mips64_clear_page_sc;
+	_copy_page = (void *)mips64_copy_page_sc;
+
+	_flush_icache_page = mips64_flush_icache_page_s;
+
+	_dma_cache_wback_inv = mips64_dma_cache_wback_inv_sc;
+	_dma_cache_wback = mips64_dma_cache_wback;
+	_dma_cache_inv = mips64_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_mips64(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+
+	probe_icache(config);
+	probe_dcache(config);
+	setup_scache(config);
+
+	_flush_cache_sigtramp = mips64_flush_cache_sigtramp;
+	_flush_icache_range = mips64_flush_icache_range;	/* Ouch */
+	_flush_icache_all = mips64_flush_icache_all;
+	_flush_cache_l1 = _flush_cache_all;
+	_flush_cache_l2 = _flush_cache_all;
+
+	__flush_cache_all();
+}
diff -urN linux-2.4.20-pre6/arch/mips64/mm/c-sb1.c linux-2.4.20-pre7/arch/mips64/mm/c-sb1.c
--- linux-2.4.20-pre6/arch/mips64/mm/c-sb1.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/c-sb1.c	Thu Sep 12 20:01:40 2002
@@ -12,11 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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>
@@ -46,7 +46,7 @@
  * 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
@@ -63,7 +63,7 @@
 	 * 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
 	 */
@@ -87,7 +87,7 @@
 		".set noreorder             \n"
 		".set mips2                 \n"
 		"sync                       \n"
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */			
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS		/* Bug 1384 */
 		"sync                       \n"
 #endif
 		".set pop                   \n");
@@ -153,7 +153,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \n" 
+		"     move   $1, %0         \n"
 		"1:                         \n"
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
 		".align 3                   \n"
@@ -192,7 +192,7 @@
 		".set noreorder             \n"
 		".set noat                  \n"
 		".set mips4                 \n"
-		"     move   $1, %0         \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 */
@@ -277,9 +277,9 @@
 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, 
+	/* 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 
+	   lw and the cache op
 	*/
 	unsigned long flags;
 	local_irq_save(flags);
@@ -370,7 +370,7 @@
 	 * 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
 	 */
@@ -402,23 +402,23 @@
 
 /*
  * 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 
+ * 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 
- *   
+ * 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 
+ * 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 
+ * 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");	
+		:::"memory");
 }
 
 /*
@@ -432,13 +432,13 @@
  * 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));
 }
 
@@ -461,7 +461,7 @@
 	} else if (config_field == 7) {
 		/* JDCXXX - Find a graceful way to abort. */
 		return 0;
-	} 
+	}
 	return (1<<(config_field + 1));
 }
 
@@ -518,6 +518,6 @@
 	_flush_cache_sigtramp = sb1_flush_cache_sigtramp;
 	_flush_icache_all = sb1_flush_icache_all;
 
-	change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
+	change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
 	flush_cache_all();
 }
diff -urN linux-2.4.20-pre6/arch/mips64/mm/extable.c linux-2.4.20-pre7/arch/mips64/mm/extable.c
--- linux-2.4.20-pre6/arch/mips64/mm/extable.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/mm/extable.c	Thu Sep 12 20:01:40 2002
@@ -40,13 +40,13 @@
 unsigned long search_exception_table(unsigned long addr)
 {
 	unsigned long ret = 0;
-	unsigned long flags;
-	
+
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 	return ret;
 #else
+	unsigned long flags;
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
 
diff -urN linux-2.4.20-pre6/arch/mips64/mm/fault.c linux-2.4.20-pre7/arch/mips64/mm/fault.c
--- linux-2.4.20-pre6/arch/mips64/mm/fault.c	Thu Sep 12 20:01:31 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/fault.c	Thu Sep 12 20:01:40 2002
@@ -126,7 +126,7 @@
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
 	 */
-	if (in_interrupt() || mm == &init_mm)
+	if (in_interrupt() || !mm)
 		goto no_context;
 
 	down_read(&mm->mmap_sem);
@@ -229,7 +229,7 @@
 	printk(KERN_ALERT "Cpu %d Unable to handle kernel paging request at "
 	       "address %016lx, epc == %016lx, ra == %016lx\n",
 	       smp_processor_id(), address, regs->cp0_epc, regs->regs[31]);
-	die("Oops", regs, write);
+	die("Oops", regs);
 
 /*
  * We ran out of memory, or some other thing happened to us that made
diff -urN linux-2.4.20-pre6/arch/mips64/mm/init.c linux-2.4.20-pre7/arch/mips64/mm/init.c
--- linux-2.4.20-pre6/arch/mips64/mm/init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/init.c	Thu Sep 12 20:01:40 2002
@@ -226,10 +226,10 @@
 
 	free_area_init(zones_size);
 
-	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
+	memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER);
 	memset((void *)kpmdtbl, 0, PAGE_SIZE);
 	pgd_set(swapper_pg_dir, kpmdtbl);
-	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
+	for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
 		pmd_val(*pmd) = (unsigned long)pte;
 }
 
@@ -243,17 +243,18 @@
 	int i;
 
 	for (i = 0; i < boot_mem_map.nr_map; i++) {
-	unsigned long addr, end;
+		unsigned long addr, end;
 
-	if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-		/* not usable memory */
-		continue;
+		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);
 
-	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;
+		if (pagenr >= addr && pagenr < end)
+			return 1;
 	}
 
 	return 0;
@@ -316,7 +317,7 @@
 	unsigned long addr, page;
 
 	prom_free_prom_memory();
-    
+
 	addr = (unsigned long)(&__init_begin);
 	while (addr < (unsigned long)&__init_end) {
 		page = PAGE_OFFSET | CPHYSADDR(addr);
diff -urN linux-2.4.20-pre6/arch/mips64/mm/loadmmu.c linux-2.4.20-pre7/arch/mips64/mm/loadmmu.c
--- linux-2.4.20-pre6/arch/mips64/mm/loadmmu.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/loadmmu.c	Thu Sep 12 20:01:40 2002
@@ -54,35 +54,29 @@
 extern void ld_mmu_andes(void);
 extern void ld_mmu_sb1(void);
 extern void sb1_tlb_init(void);
+extern void ld_mmu_mips64(void);
+extern void r4k_tlb_init(void);
 
 void __init load_mmu(void)
 {
-	switch(mips_cpu.cputype) {
+	if (mips_cpu.options & MIPS_CPU_4KTLB) {
 #if defined (CONFIG_CPU_R4300)						\
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
     || defined (CONFIG_CPU_NEVADA)
-	case CPU_R4000PC:
-	case CPU_R4000SC:
-	case CPU_R4000MC:
-	case CPU_R4200:
-	case CPU_R4300:
-	case CPU_R4400PC:
-	case CPU_R4400SC:
-	case CPU_R4400MC:
-	case CPU_R4600:
-	case CPU_R4640:
-	case CPU_R4650:
-	case CPU_R4700:
-	case CPU_R5000:
-	case CPU_R5000A:
-	case CPU_NEVADA:
 		printk(KERN_INFO "Loading R4000 MMU routines.\n");
 		ld_mmu_r4xx0();
-		break;
 #endif
+#if defined(CONFIG_CPU_MIPS64)
+		printk(KERN_INFO "Loading MIPS64 MMU routines.\n");
+                ld_mmu_mips64();
+		r4k_tlb_init();
+#endif
+
+	} else switch(mips_cpu.cputype) {
 #ifdef CONFIG_CPU_R10000
 	case CPU_R10000:
+	case CPU_R12000:
 		printk(KERN_INFO "Loading R10000 MMU routines.\n");
 		ld_mmu_andes();
 		break;
@@ -95,6 +89,10 @@
 		break;
 #endif
 
+	case CPU_R8000:
+		panic("R8000 is unsupported");
+		break;
+
 	default:
 		/* XXX We need an generic routine in the MIPS port
 		 * XXX to jabber stuff onto the screen on all machines
diff -urN linux-2.4.20-pre6/arch/mips64/mm/pg-mips64.c linux-2.4.20-pre7/arch/mips64/mm/pg-mips64.c
--- linux-2.4.20-pre6/arch/mips64/mm/pg-mips64.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips64/mm/pg-mips64.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,126 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * MIPS64 CPU variant specific Cache routines.
+ * These routine are not optimized in any way, they are done in a generic way
+ * so they can be used on all MIPS64 compliant CPUs, and also done in an
+ * attempt not to break anything for the R4xx0 style CPUs.
+ */
+#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 mips64_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"
+				"cache\t%2,(%0)\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+=sizeof(long))
+	        *(unsigned long *)(i) = 0;
+}
+
+void mips64_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"
+				"cache\t%2,(%0)\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+=sizeof(long))
+	        *(unsigned long *)(i) = 0;
+}
+
+void mips64_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"
+				"cache\t%2,(%0)\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_D));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=sizeof(long))
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
+
+void mips64_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"
+				"cache\t%2,(%0)\n\t"
+				".set\tat\n\t"
+				".set\treorder"
+				:"=r" (i)
+				:"0" (i),
+				"I" (Create_Dirty_Excl_SD));
+		}
+	}
+	for (i=0; i<PAGE_SIZE; i+=sizeof(long))
+	        *(unsigned long *)(to+i) = *(unsigned long *)(from+i);
+}
diff -urN linux-2.4.20-pre6/arch/mips64/mm/pg-sb1.c linux-2.4.20-pre7/arch/mips64/mm/pg-sb1.c
--- linux-2.4.20-pre6/arch/mips64/mm/pg-sb1.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/pg-sb1.c	Thu Sep 12 20:01:40 2002
@@ -2,7 +2,7 @@
  * 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)
  *
  *
@@ -15,11 +15,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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>
 
@@ -40,7 +40,7 @@
 	 * 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 
+	 * since we know we're on an SB1, we force the assembler to take
 	 * 64-bit operands to speed things up
 	 */
 	__asm__ __volatile__(
@@ -50,9 +50,9 @@
 		".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"  
+		"     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"
@@ -72,7 +72,7 @@
 	/*
 	 * 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 
+	 * 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
@@ -88,11 +88,11 @@
 		".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_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_STORE_STREAMED_HINT ",  32(%1) \n"
 		"     pref       " SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0) \n"
-		"     pref       " SB1_PREF_STORE_STREAMED_HINT ",  64(%1) \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"
@@ -103,20 +103,20 @@
 		"     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        $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"		
+		"     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" 
+		".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 -urN linux-2.4.20-pre6/arch/mips64/mm/r4xx0.c linux-2.4.20-pre7/arch/mips64/mm/r4xx0.c
--- linux-2.4.20-pre6/arch/mips64/mm/r4xx0.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/r4xx0.c	Thu Sep 12 20:01:40 2002
@@ -136,10 +136,10 @@
  *      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 
+ *      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 
+ *      four instructions that are not any kind of load or store
  *      instruction.
  *
  *      This is not allowed:    lw
@@ -1237,7 +1237,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1285,7 +1285,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1335,7 +1335,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1385,7 +1385,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/*
 		 * Do indexed flush, too much work to get the (possible)
@@ -1434,7 +1434,7 @@
 	 * for every cache flush operation.  So we do indexed flushes
 	 * in that case, which doesn't overly flush the cache too much.
 	 */
-	if (CPU_CONTEXT(smp_processor_id(), mm) != 
+	if (CPU_CONTEXT(smp_processor_id(), mm) !=
 	    CPU_CONTEXT(smp_processor_id(), current->mm)) {
 		/* Do indexed flush, too much work to get the (possible)
 		 * tlb refills to work correctly.
@@ -1746,11 +1746,6 @@
 	}
 }
 
-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
@@ -1877,7 +1872,7 @@
 		} else {
 			get_new_mmu_context(mm, smp_processor_id());
 			if(mm == current->mm)
-				set_entryhi(CPU_CONTEXT(smp_processor_id(), 
+				set_entryhi(CPU_CONTEXT(smp_processor_id(),
 								mm) & 0xff);
 		}
 		__restore_flags(flags);
@@ -2152,7 +2147,7 @@
 	}
 	_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_wback = r4k_dma_cache_wback_inv_pc;
 	_dma_cache_inv = r4k_dma_cache_inv_pc;
 }
 
@@ -2241,11 +2236,12 @@
 	}
 	_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_wback = r4k_dma_cache_wback_inv_sc;
 	_dma_cache_inv = r4k_dma_cache_inv_sc;
 }
 
 typedef int (*probe_func_t)(unsigned long);
+extern int r5k_sc_init(void);
 
 static inline void __init setup_scache(unsigned int config)
 {
@@ -2256,23 +2252,30 @@
 	probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
 	sc_present = probe_scache_kseg1(config);
 
-	if (sc_present) {
-		setup_scache_funcs();
+	if (!sc_present) {
+		setup_noscache_funcs();
 		return;
 	}
 
-	setup_noscache_funcs();
+	switch(mips_cpu.cputype) {
+	case CPU_R5000:
+	case CPU_NEVADA:
+			setup_noscache_funcs();
+#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)
+			r5k_sc_init();
+#endif
+			break;
+	default:
+			setup_scache_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 /* UNCACHED */
+	change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT);
 
 	probe_icache(config);
 	probe_dcache(config);
diff -urN linux-2.4.20-pre6/arch/mips64/mm/r5k-sc.c linux-2.4.20-pre7/arch/mips64/mm/r5k-sc.c
--- linux-2.4.20-pre6/arch/mips64/mm/r5k-sc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips64/mm/r5k-sc.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,115 @@
+/*
+ * 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/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcacheops.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#define SC_LINE 32
+#define SC_PAGE (128*SC_LINE)
+
+#define cache_op(base,op)                   \
+__asm__ __volatile__("				\
+		.set noreorder;                 \
+		.set mips3;                     \
+		cache %1, (%0);                 \
+		.set mips0;                     \
+		.set reorder"                   \
+		:                               \
+		: "r" (base),                   \
+		  "i" (op));
+
+static inline void blast_r5000_scache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache_op(start, R5K_Page_Invalidate_S);
+		start += SC_PAGE;
+	}
+}
+
+static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+	unsigned long end, a;
+
+	if (size >= scache_size) {
+		blast_r5000_scache();
+		return;
+	}
+
+	/* On the R5000 secondary cache we cannot
+	 * invalidate less than a page at a time.
+	 * The secondary cache is physically indexed, write-through.
+	 */
+	a = addr & ~(SC_PAGE - 1);
+	end = (addr + size - 1) & ~(SC_PAGE - 1);
+	while (a <= end) {
+		cache_op(a, R5K_Page_Invalidate_S);
+		a += SC_PAGE;
+	}
+}
+
+static void r5k_sc_enable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	change_cp0_config(CONF_SE, CONF_SE);
+	blast_r5000_scache();
+	__restore_flags(flags);
+}
+
+static void r5k_sc_disable(void)
+{
+        unsigned long flags;
+
+	__save_and_cli(flags);
+	blast_r5000_scache();
+	change_cp0_config(CONF_SE, 0);
+	__restore_flags(flags);
+}
+
+static inline int __init r5k_sc_probe(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	if(config & CONF_SC)
+		return(0);
+
+	scache_size = (512*1024) << ((config >> 20)&3);
+
+	printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+			scache_size >> 10);
+
+	return 1;
+}
+
+struct bcache_ops r5k_sc_ops = {
+	r5k_sc_enable,
+	r5k_sc_disable,
+	r5k_dma_cache_inv_sc,
+	r5k_dma_cache_inv_sc
+};
+
+void __init r5k_sc_init(void)
+{
+	if (r5k_sc_probe()) {
+		r5k_sc_enable();
+		bcops = &r5k_sc_ops;
+	}
+}
diff -urN linux-2.4.20-pre6/arch/mips64/mm/tlb-r4k.c linux-2.4.20-pre7/arch/mips64/mm/tlb-r4k.c
--- linux-2.4.20-pre6/arch/mips64/mm/tlb-r4k.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/arch/mips64/mm/tlb-r4k.c	Thu Sep 12 20:01:40 2002
@@ -0,0 +1,407 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * MIPS64 CPU variant specific MMU routines.
+ * These routine are not optimized in any way, they are done in a generic way
+ * so they can be used on all MIPS64 compliant CPUs, and also done in an
+ * attempt not to break anything for the R4xx0 style CPUs.
+ */
+#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_vec1_r4k;
+
+/* 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_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 local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if (CPU_CONTEXT(smp_processor_id(), mm) != 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(CPU_CONTEXT(smp_processor_id(), mm) &
+				    0xff);
+		__restore_flags(flags);
+	}
+}
+
+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);
+#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 = (CPU_CONTEXT(smp_processor_id(), 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);
+				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, smp_processor_id());
+			if (mm == current->active_mm)
+				set_entryhi(CPU_CONTEXT(smp_processor_id(),
+							mm) & 0xff);
+		}
+		__restore_flags(flags);
+	}
+}
+
+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;
+		unsigned long oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+		printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+		newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 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);
+	}
+}
+
+/*
+ * Updates the TLB with the new pte(s).
+ */
+void mips64_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 != (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);
+	}
+#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 dump_mm_page(unsigned long addr)
+{
+	pgd_t	*page_dir, *pgd;
+	pmd_t	*pmd;
+	pte_t	*pte, page;
+	unsigned long val;
+
+	page_dir = pgd_offset(current->mm, 0);
+	pgd = pgd_offset(current->mm, addr);
+	pmd = pmd_offset(pgd, addr);
+	pte = pte_offset(pmd, addr);
+	page = *pte;
+	printk("Memory Mapping: VA = %08x, PA = %08x ", addr, (unsigned int) pte_val(page));
+	val = pte_val(page);
+	if (val & _PAGE_PRESENT) printk("present ");
+	if (val & _PAGE_READ) printk("read ");
+	if (val & _PAGE_WRITE) printk("write ");
+	if (val & _PAGE_ACCESSED) printk("accessed ");
+	if (val & _PAGE_MODIFIED) printk("modified ");
+	if (val & _PAGE_R4KBUG) printk("r4kbug ");
+	if (val & _PAGE_GLOBAL) printk("global ");
+	if (val & _PAGE_VALID) printk("valid ");
+	printk("\n");
+}
+
+void show_tlb(void)
+{
+        unsigned int flags;
+        unsigned int old_ctx;
+	unsigned int entry;
+	unsigned int entrylo0, entrylo1, entryhi;
+
+	__save_and_cli(flags);
+
+	/* Save old context */
+	old_ctx = (get_entryhi() & 0xff);
+
+	printk("TLB content:\n");
+	entry = 0;
+	while(entry < mips_cpu.tlbsize) {
+		set_index(entry);
+		BARRIER;
+		tlb_read();
+		BARRIER;
+		entryhi = get_entryhi();
+		entrylo0 = get_entrylo0();
+		entrylo1 = get_entrylo1();
+		printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : "   ", entryhi & ~ASID_MASK);
+		printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : "");
+		printk("\t\t\t     PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : "");
+
+		dump_mm_page(entryhi & ~0xff);
+		dump_mm_page((entryhi & ~0xff) | 0x1000);
+		entry++;
+	}
+	BARRIER;
+	set_entryhi(old_ctx);
+
+	__restore_flags(flags);
+}
+
+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);
+        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 long config1;
+
+        if (!(config & (1 << 31))) {
+	        /*
+		 * Not a MIPS64 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 r4k_tlb_init(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	probe_tlb(config);
+	_update_mmu_cache = mips64_update_mmu_cache;
+	set_pagemask(PM_4K);
+	write_32bit_cp0_register(CP0_WIRED, 0);
+	temp_tlb_entry = mips_cpu.tlbsize - 1;
+	local_flush_tlb_all();
+
+	memcpy((void *)(KSEG0 + 0x80), &except_vec1_r4k, 0x80);
+	flush_icache_range(KSEG0, KSEG0 + 0x80);
+}
diff -urN linux-2.4.20-pre6/arch/mips64/mm/tlb-sb1.c linux-2.4.20-pre7/arch/mips64/mm/tlb-sb1.c
--- linux-2.4.20-pre6/arch/mips64/mm/tlb-sb1.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/tlb-sb1.c	Thu Sep 12 20:01:40 2002
@@ -12,11 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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>
@@ -37,13 +37,13 @@
 		"     tlbr             \n"
 		"     dmfc0  $1, $10   \n"
 		"     dsrl32 %0, $1, 0 \n"
-		"     sra    %1, $1, 0 \n"
+		"     sll    %1, $1, 0 \n"
 		"     dmfc0  $1, $2    \n"
 		"     dsrl32 %2, $1, 0 \n"
-		"     sra    %3, $1, 0 \n"
+		"     sll    %3, $1, 0 \n"
 		"     dmfc0  $1, $3    \n"
 		"     dsrl32 %4, $1, 0 \n"
-		"     sra    %5, $1, 0 \n"
+		"     sll    %5, $1, 0 \n"
 		"     mfc0   %6, $5    \n"
 		".set pop              \n"
 		: "=r" (entryhihi),
@@ -62,7 +62,11 @@
 
 void sb1_dump_tlb(void)
 {
+	unsigned long old_ctx;
+	unsigned long flags;
 	int entry;
+	__save_and_cli(flags);
+	old_ctx = get_entryhi();
 	printk("Current TLB registers state:\n"
 	       "      EntryHi       EntryLo0          EntryLo1     PageMask  Index\n"
 	       "--------------------------------------------------------------------\n");
@@ -83,6 +87,8 @@
 		dump_cur_tlb_regs();
 	}
 	printk("\n");
+	set_entryhi(old_ctx);
+	__restore_flags(flags);
 }
 
 void local_flush_tlb_all(void)
@@ -102,12 +108,12 @@
 		tlb_write_indexed();
 	}
 	set_entryhi(old_ctx);
-	__restore_flags(flags);	
+	__restore_flags(flags);
 }
 
 
 /*
- * Use a bogus region of memory (starting at 0) to sanitize the TLB's.  
+ * 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
@@ -209,7 +215,7 @@
 		set_entrylo1(0);
 		if(idx < 0)
 			goto finish;
-		/* Make sure all entries differ. */  
+		/* Make sure all entries differ. */
 		set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1)));
 		tlb_write_indexed();
 	finish:
@@ -299,7 +305,7 @@
 	/*
 	 * 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 
+	 * check exceptions due to duplicate TLB entries
 	 */
 	sb1_sanitize_tlb();
 	_update_mmu_cache = sb1_update_mmu_cache;
diff -urN linux-2.4.20-pre6/arch/mips64/mm/tlbex-r4k.S linux-2.4.20-pre7/arch/mips64/mm/tlbex-r4k.S
--- linux-2.4.20-pre6/arch/mips64/mm/tlbex-r4k.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/mm/tlbex-r4k.S	Thu Sep 12 20:01:40 2002
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -20,10 +21,9 @@
 
 	/*
 	 * After this macro runs we have a pointer to the pte of the address
-	 * that caused the fault in in PTR.
+	 * that caused the fault in PTR.
 	 */
-
-	.macro	LOAD_PTE2, ptr, tmp
+	.macro	LOAD_PTE2, ptr, tmp, kaddr
 #ifdef CONFIG_SMP
 	dmfc0	\ptr, CP0_CONTEXT
 	dmfc0	\tmp, CP0_BADVADDR
@@ -32,8 +32,8 @@
 	dmfc0	\tmp, CP0_BADVADDR
 	dla	\ptr, pgd_current
 #endif
-	bltz	\tmp, kaddr
-	ld	\ptr, (\ptr)
+	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
@@ -48,6 +48,35 @@
 	daddu	\ptr, \tmp
 	.endm
 
+
+	/*
+	 * Ditto for the kernel table.
+	 */
+	.macro	LOAD_KPTE2, ptr, tmp, not_vmalloc
+	/*
+	 * First, determine that the address is in/above vmalloc range.
+	 */
+	dmfc0	\tmp, CP0_BADVADDR
+	dli	\ptr, VMALLOC_START
+
+	/*
+	 * Now find offset into kptbl.
+	 */
+	dsubu	\tmp, \tmp, \ptr
+	dla	\ptr, kptbl
+	dsrl	\tmp, (PAGE_SHIFT+1)		# get vpn2
+	dsll	\tmp, 4				# byte offset of pte
+	daddu	\ptr, \ptr, \tmp
+
+	/*
+	 * Determine that fault address is within vmalloc range.
+	 */
+	dla	\tmp, ekptbl
+	sltu	\tmp, \ptr, \tmp
+	beqz	\tmp, \not_vmalloc		# not vmalloc
+	.endm
+
+
 	/*
 	 * This places the even/odd pte pair in the page table at the pte
 	 * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1.
@@ -59,6 +88,7 @@
 	dmtc0	\pte1, CP0_ENTRYLO1		# load it
 	.endm
 
+
 	.text
 	.set	noreorder
 	.set	mips3
@@ -66,69 +96,93 @@
 	__INIT
 
 	.align	5
-FEXPORT(except_vec0)
+LEAF(except_vec0)
 	.set	noat
 	PANIC("Unused vector called")
 1:	b	1b
 	 nop
+END(except_vec0)
+
 
 	/*
-	 * TLB refill handler for the R10000.
+	 * TLB refill handler for the R4000.
 	 * Attention:  We may only use 32 instructions / 128 bytes.
 	 */
+	.align  5
+LEAF(except_vec1_r4k)
+	.set    noat
+	dla     k0, handle_vec1_r4k
+	jr      k0
+	 nop
+END(except_vec1_r4k)
 
-	.align	5
-LEAF(except_vec1_r10k)
-	.set	noat
-	LOAD_PTE2 k1 k0
+	__FINIT
+
+	.align  5
+LEAF(handle_vec1_r4k)
+	.set    noat
+	LOAD_PTE2 k1 k0 9f
 	ld	k0, 0(k1)			# get even pte
 	ld	k1, 8(k1)			# get odd pte
 	PTE_RELOAD k0 k1
-	nop
-	tlbwr
+	b	1f
+	 tlbwr
+1:	nop
 	eret
-kaddr:
-	dla	k0, handle_vmalloc_address	# MAPPED kernel needs this
-	jr	k0
-	 nop
-	END(except_vec1_r10k)
 
-	__FINIT
+9:						# handle the vmalloc range
+	LOAD_KPTE2 k1 k0 invalid_vmalloc_address
+	ld	k0, 0(k1)			# get even pte
+	ld	k1, 8(k1)			# get odd pte
+	PTE_RELOAD k0 k1
+	b	1f
+	 tlbwr
+1:	nop
+	eret
+END(handle_vec1_r4k)
 
-	.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
+	__INIT
 
 	/*
-	 * Now find offset into kptbl.
+	 * TLB refill handler for the R10000.
+	 * Attention:  We may only use 32 instructions / 128 bytes.
 	 */
-	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
+	.align	5
+LEAF(except_vec1_r10k)
+	.set    noat
+	dla     k0, handle_vec1_r10k
+	jr      k0
+	 nop
+END(except_vec1_r10k)
 
-	/*
-	 * Determine that fault address is within vmalloc range.
-	 */
-	dla	k0, ekptbl
-	sltu	k0, k1, k0
-	beqz	k0, not_vmalloc
+	__FINIT
 
-	/*
-	 * Load cp0 registers.
-	 */
+	.align	5
+LEAF(handle_vec1_r10k)
+	.set	noat
+	LOAD_PTE2 k1 k0 9f
 	ld	k0, 0(k1)			# get even pte
 	ld	k1, 8(k1)			# get odd pte
+	PTE_RELOAD k0 k1
+	nop
+	tlbwr
+	eret
 
-not_vmalloc:
+9:						# handle the vmalloc range
+	LOAD_KPTE2 k1 k0 invalid_vmalloc_address
+	ld	k0, 0(k1)			# get even pte
+	ld	k1, 8(k1)			# get odd pte
 	PTE_RELOAD k0 k1
 	nop
 	tlbwr
 	eret
-	END(handle_vmalloc_address)
+END(handle_vec1_r10k)
+
+
+	.align	5
+LEAF(invalid_vmalloc_address)
+	.set	noat
+	PANIC("Invalid kernel address")
+1:	b	1b
+	 nop
+END(invalid_vmalloc_address)
diff -urN linux-2.4.20-pre6/arch/mips64/mm/umap.c linux-2.4.20-pre7/arch/mips64/mm/umap.c
--- linux-2.4.20-pre6/arch/mips64/mm/umap.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/mm/umap.c	Thu Sep 12 20:01:40 2002
@@ -51,7 +51,7 @@
 		address += PAGE_SIZE;
 		pte++;
 	} while (address < end);
-						  
+
 }
 
 static inline void remove_mapping_pmd_range (pgd_t *pgd, unsigned long address,
@@ -79,7 +79,7 @@
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
-		
+
 }
 
 /*
@@ -137,7 +137,7 @@
 
 /*
  * maps a range of vmalloc()ed memory into the requested pages. the old
- * mappings are removed. 
+ * mappings are removed.
  */
 static inline void vmap_pte_range (pte_t *pte, unsigned long address,
 				   unsigned long size, unsigned long vaddr)
@@ -146,7 +146,7 @@
 	pgd_t *vdir;
 	pmd_t *vpmd;
 	pte_t *vpte;
-	
+
 	address &= ~PMD_MASK;
 	end = address + size;
 	if (end > PMD_SIZE)
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/Makefile linux-2.4.20-pre7/arch/mips64/sgi-ip27/Makefile
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,15 +0,0 @@
-#
-# Makefile for the IP27 specific kernel interface routines under Linux.
-#
-
-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
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/TODO linux-2.4.20-pre7/arch/mips64/sgi-ip27/TODO
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/TODO	Sat May 13 08:30:17 2000
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/TODO	Wed Dec 31 16:00:00 1969
@@ -1,23 +0,0 @@
-1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
-not to write to the IOC3 ever.
-2. Need to figure out RRB allocation in bridge_startup().
-3. Need to figure out why address swaizzling is needed in inw/outw for 
-Qlogic scsi controllers.
-4. Need to integrate ip27-klconfig.c:find_lboard and 
-ip27-init.c:find_lbaord_real. DONE
-5. Is it okay to set calias space on all nodes as 0, instead of 8k as
-in irix?
-6. Investigate why things do not work without the setup_test() call
-being invoked on all nodes in ip27-memory.c.
-7. Too many CLIs in the locore handlers :
-For the low level handlers set up by set_except_vector(), 
-__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
-investigate whether the code should do CLI, STI or KMODE. 
-8. Too many do_page_faults invoked - investigate.
-9. start_thread must turn off UX64 ... and define tlb_refill_debug.
-10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
-does not agree with pgd_bad/pmd_bad.
-11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node.
-This might need to change later. Only the timer intr is set up to be
-received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
-13. Cache flushing (specially the SMP version) has to be investigated.
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-berr.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-berr.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-berr.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-berr.c	Wed Dec 31 16:00:00 1969
@@ -1,93 +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
- * Copyright (C) 2002  Maciej W. Rozycki
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/module.h>
-#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);
-
-static void dump_hub_information(unsigned long errst0, unsigned long errst1)
-{
-	static char *err_type[2][8] = {
-		{ NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
-		  NULL, NULL, NULL, NULL },
-		{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
-		  NULL, NULL, NULL, NULL }
-	};
-	int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
-
-	if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
-		printk("Hub does not contain valid error information\n");
-		return;
-	}
-
-	
-	printk("Hub has valid error information:\n");
-	if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
-		printk("Overrun is set.  Error stack may contain additional "
-		       "information.\n");
-	printk("Hub error address is %08lx\n",
-	       (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
-	printk("Incoming message command 0x%lx\n",
-	       (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
-	printk("Supplemental field of incoming message is 0x%lx\n",
-	       (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
-	printk("T5 Rn (for RRB only) is 0x%lx\n",
-	       (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
-	printk("Error type is %s\n", err_type[wrb]
-	       [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
-		? : "invalid");
-}
-
-int be_ip27_handler(struct pt_regs *regs, int is_fixup)
-{
-	unsigned long errst0, errst1;
-	int data = regs->cp0_cause & 4;
-	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
-
-	if (is_fixup)
-		return MIPS_BE_FIXUP;
-
-	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);
-	errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
-	dump_hub_information(errst0, errst1);
-	show_regs(regs);
-	dump_tlb_all();
-	while(1);
-	force_sig(SIGBUS, current);
-}
-
-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;
-
-	be_board_handler = be_ip27_handler;
-
-	LOCAL_HUB_S(PI_ERR_INT_PEND,
-	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
-	LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
-	LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
-	LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0);	/* Disable error stack */
-	LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-console.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-console.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-console.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-console.c	Wed Dec 31 16:00:00 1969
@@ -1,58 +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) 2001 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn0/hub.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/sn_private.h>
-
-void prom_putchar(char c)
-{
-	struct ioc3 *ioc3;
-	struct ioc3_uartregs *uart;
-
-	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base;
-	uart = &ioc3->sregs.uarta;
-
-	while ((uart->iu_lsr & 0x20) == 0);
-	uart->iu_thr = c;
-}
-
-char __init prom_getchar(void)
-{
-	return 0;
-}
-
-static void
-ip27prom_console_write(struct console *con, const char *s, unsigned n)
-{
-	prom_printf("%s", s);
-}
-
-static kdev_t 
-ip27prom_console_dev(struct console *c)
-{
-	return MKDEV(TTY_MAJOR, 64 + c->index);
-}
-
-static struct console ip27_prom_console = {
-    name:	"prom",
-    write:	ip27prom_console_write,
-    device:	ip27prom_console_dev,
-    flags:	CON_PRINTBUFFER,
-    index:	-1,
-};
-
-__init void ip27_setup_console(void)
-{
-	register_console(&ip27_prom_console);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-dbe-glue.S linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-dbe-glue.S
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-dbe-glue.S	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-dbe-glue.S	Wed Dec 31 16:00:00 1969
@@ -1,20 +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 - 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 -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-init.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-init.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-init.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-init.c	Wed Dec 31 16:00:00 1969
@@ -1,838 +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 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
- * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#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>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/sn0/hubio.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/ioc3.h>
-#include <asm/mipsregs.h>
-#include <asm/sn/gda.h>
-#include <asm/sn/intr.h>
-#include <asm/current.h>
-#include <asm/smp.h>
-#include <asm/processor.h>
-#include <asm/mmu_context.h>
-#include <asm/sn/launch.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/mapped_kernel.h>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/gda.h>
-
-#define CPU_NONE		(cpuid_t)-1
-
-/*
- * The following should work till 64 nodes, ie 128p SN0s.
- */
-#define CNODEMASK_CLRALL(p)	(p) = 0
-#define CNODEMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
-#define CNODEMASK_SETB(p, bit)	((p) |= 1ULL << (bit))
-
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-static int	fine_mode = 0;
-int		maxcpus;
-static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED;
-static cnodemask_t hub_init_mask;
-static atomic_t numstarted = ATOMIC_INIT(1);
-static int router_distance;
-nasid_t master_nasid = INVALID_NASID;
-
-cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
-nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
-cnodeid_t	cpuid_to_compact_node[MAXCPUS];
-char		node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
-
-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;
-}
-
-static void gen_region_mask(hubreg_t *region_mask, int maxnodes)
-{
-	cnodeid_t cnode;
-
-	(*region_mask) = 0;
-	for (cnode = 0; cnode < maxnodes; cnode++) {
-		(*region_mask) |= 1ULL << get_region(cnode);
-	}
-}
-
-int is_fine_dirmode(void)
-{
-	return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
-		>> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
-}
-
-nasid_t get_actual_nasid(lboard_t *brd)
-{
-	klhub_t *hub;
-
-	if (!brd)
-		return INVALID_NASID;
-
-	/* find out if we are a completely disabled brd. */
-	hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-		return INVALID_NASID;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid;
-	else
-		return brd->brd_nasid;
-}
-
-/* Tweak this for maximum number of CPUs to activate */
-static int max_cpus = NR_CPUS;
-
-int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask, 
-							int *highest)
-{
-	static int tot_cpus_found = 0;
-	lboard_t *brd;
-	klcpu_t *acpu;
-	int cpus_found = 0;
-	cpuid_t cpuid;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
-
-	do {
-		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
-		while (acpu) {
-			cpuid = acpu->cpu_info.virtid;
-			/* cnode is not valid for completely disabled brds */
-			if (get_actual_nasid(brd) == brd->brd_nasid)
-				cpuid_to_compact_node[cpuid] = cnode;
-			if (cpuid > *highest)
-				*highest = cpuid;
-			/* Only let it join in if it's marked enabled */
-			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
-						(tot_cpus_found != max_cpus)) {
-				CPUMASK_SETB(*boot_cpumask, cpuid);
-				cpus_found++;
-				tot_cpus_found++;
-			}
-			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 
-								KLSTRUCT_CPU);
-		}
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd,KLTYPE_IP27);
-		else
-			break;
-	} while (brd);
-
-	return cpus_found;
-}
-
-cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes)
-{
-	int i, cpus = 0, highest = 0;
-	gda_t *gdap = GDA;
-	nasid_t nasid;
-
-	/*
-	 * Initialize the arrays to invalid nodeid (-1)
-	 */
-	for (i = 0; i < MAX_COMPACT_NODES; i++)
-		compact_to_nasid_node[i] = INVALID_NASID;
-	for (i = 0; i < MAX_NASIDS; i++)
-		nasid_to_compact_node[i] = INVALID_CNODEID;
-	for (i = 0; i < MAXCPUS; i++)
-		cpuid_to_compact_node[i] = INVALID_CNODEID;
-
-	*numnodes = 0;
-	for (i = 0; i < MAX_COMPACT_NODES; i++) {
-		if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) {
-			break;
-		} else {
-			compact_to_nasid_node[i] = nasid;
-			nasid_to_compact_node[nasid] = i;
-			(*numnodes)++;
-			cpus += do_cpumask(i, nasid, boot_cpumask, &highest);
-		}
-	}
-
-	/*
-	 * Cpus are numbered in order of cnodes. Currently, disabled
-	 * cpus are not numbered.
-	 */
-
-	return(highest + 1);
-}
-
-int cpu_enabled(cpuid_t cpu)
-{
-	if (cpu == CPU_NONE)
-		return 0;
-	return (CPUMASK_TSTB(boot_cpumask, cpu) != 0);
-}
-
-void mlreset (void)
-{
-	int i;
-	void init_topology_matrix(void);
-	void dump_topology(void);
-
-
-	master_nasid = get_nasid();
-	fine_mode = is_fine_dirmode();
-
-	/*
-	 * Probe for all CPUs - this creates the cpumask and
-	 * sets up the mapping tables.
-	 */
-	CPUMASK_CLRALL(boot_cpumask);
-	maxcpus = cpu_node_probe(&boot_cpumask, &numnodes);
-	printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes);
-
-	init_topology_matrix();
-	dump_topology();
-
-	gen_region_mask(&region_mask, numnodes);
-	CNODEMASK_CLRALL(hub_init_mask);
-
-	setup_replication_mask(numnodes);
-
-	/*
-	 * Set all nodes' calias sizes to 8k
-	 */
-	for (i = 0; i < numnodes; i++) {
-		nasid_t nasid;
-
-		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.
-		 */
-		REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
-#ifdef CONFIG_REPLICATE_EXHANDLERS
-		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
-#else
-		REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
-#endif
-
-#ifdef LATER
-		/*
-		 * Set up all hubs to have 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
-	}
-}
-
-
-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))
-				LOCAL_HUB_CLR_INTR(base_level + i);
-}
-	
-void intr_clear_all(nasid_t nasid)
-{
-	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
-	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
-	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
-	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
-	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0),
-		INT_PEND0_BASELVL, "INT_PEND0");
-	intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1),
-		INT_PEND1_BASELVL, "INT_PEND1");
-}
-
-void sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-#if 0
-	cpuid_t		cpu;
-#endif
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-#if 0
-		init_platform_nodepda();
-#endif
-		intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-	}
-#if 0
-	for (cpu = 0; cpu < maxcpus; cpu++) {
-		init_platform_pda();
-	}
-#endif
-}
-
-void per_hub_init(cnodeid_t cnode)
-{
-	extern void pcibr_setup(cnodeid_t);
-	cnodemask_t	done;
-	nasid_t		nasid;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	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);
-		/*
-	 	 * Do the actual initialization if it hasn't been done yet.
-	 	 * We don't need to hold a lock for this work.
-	 	 */
-		/*
-		 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
-		 */
-		REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
-		REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-		hub_rtc_init(cnode);
-		pcibr_setup(cnode); 
-#ifdef CONFIG_REPLICATE_EXHANDLERS
-		/*
-		 * If this is not a headless node initialization, 
-		 * copy over the caliased exception handlers.
-		 */
-		if (get_compact_nodeid() == cnode) {
-			extern char except_vec0, except_vec1_r10k;
-			extern char except_vec2_generic, except_vec3_generic;
-
-			memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic,
-								0x80);
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-								0x80);
-			memcpy((void *)KSEG0, &except_vec0, 0x80);
-			memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80);
-			memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
-			memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
-								0x100);
-			flush_cache_l1();
-			flush_cache_l2();
-		}
-#endif
-	}
-	spin_unlock(&hub_mask_lock);
-}
-
-/*
- * This is similar to hard_smp_processor_id().
- */
-cpuid_t getcpuid(void)
-{
-	klcpu_t *klcpu;
-
-	klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM));
-	return klcpu->cpu_info.virtid;
-}
-
-void per_cpu_init(void)
-{
-	extern void install_cpu_nmi_handler(int slice);
-	extern void load_mmu(void);
-	static int is_slave = 0;
-	int cpu = smp_processor_id();
-	cnodeid_t cnode = get_compact_nodeid();
-
-	TLBMISS_HANDLER_SETUP();
-#if 0
-	intr_init();
-#endif
-	clear_cp0_status(ST0_IM);
-	per_hub_init(cnode);
-	cpu_time_init();
-	if (smp_processor_id())	/* master can't do this early, no kmalloc */
-		install_cpuintr(cpu);
-	/* Install our NMI handler if symmon hasn't installed one. */
-	install_cpu_nmi_handler(cputoslice(cpu));
-#if 0
-	install_tlbintr(cpu);
-#endif
-	set_cp0_status(SRB_DEV0 | SRB_DEV1);
-	if (is_slave) {
-		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);
-	} else {
-		is_slave = 1;
-	}
-}
-
-cnodeid_t get_compact_nodeid(void)
-{
-	nasid_t nasid;
-
-	nasid = get_nasid();
-	/*
-	 * Map the physical node id to a virtual node id (virtual node ids
-	 * are contiguous).
-	 */
-	return NASID_TO_COMPACT_NODEID(nasid);
-}
-
-#ifdef CONFIG_SMP
-
-/*
- * Takes as first input the PROM assigned cpu id, and the kernel
- * assigned cpu id as the second.
- */
-static void alloc_cpupda(cpuid_t cpu, int cpunum)
-{
-	cnodeid_t	node;
-	nasid_t		nasid;
-
-	node = get_cpu_cnode(cpu);
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	cputonasid(cpunum) = nasid;
-	cputocnode(cpunum) = node;
-	cputoslice(cpunum) = get_cpu_slice(cpu);
-	cpu_data[cpunum].p_cpuid = cpu;
-}
-
-static volatile cpumask_t boot_barrier;
-
-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
-	local_flush_tlb_all();
-	flush_cache_l1();
-	flush_cache_l2();
-	start_secondary();
-}
-
-__init void allowboot(void)
-{
-	int		num_cpus = 0;
-	cpuid_t		cpu, mycpuid = getcpuid();
-	cnodeid_t	cnode;
-	extern void	smp_bootstrap(void);
-
-	sn_mp_setup();
-	/* Master has already done per_cpu_init() */
-	install_cpuintr(smp_processor_id());
-#if 0
-	bte_lateinit();
-	ecc_init();
-#endif
-
-	replicate_kernel_text(numnodes);
-	boot_barrier = boot_cpumask;
-	/* Launch slaves. */
-	for (cpu = 0; cpu < maxcpus; cpu++) {
-		if (cpu == mycpuid) {
-			alloc_cpupda(cpu, num_cpus);
-			num_cpus++;
-			/* We're already started, clear our bit */
-			CPUMASK_CLRB(boot_barrier, cpu);
-			continue;
-		}
-
-		/* Skip holes in CPU space */
-		if (CPUMASK_TSTB(boot_cpumask, cpu)) {
-			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", num_cpus);
-			init_tasks[num_cpus] = p;
-			alloc_cpupda(cpu, num_cpus);
-			del_from_runqueue(p);
-			p->processor = num_cpus;
-			p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */
-			unhash_process(p);
-			/* Attach to the address space of init_task. */
-			atomic_inc(&init_mm.mm_count);
-			p->active_mm = &init_mm;
-
-			/*
-		 	 * 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(smp_bootstrap),
-				0, (void *)((unsigned long)p + 
-				KERNEL_STACK_SIZE - 32), (void *)p);
-
-			/*
-			 * Now optimistically set the mapping arrays. We
-			 * need to wait here, verify the cpu booted up, then
-			 * fire up the next cpu.
-			 */
-			__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,
-			 * and discover the io devices it will control.
-			 * 
-			 * XXX: We really want to fire up launch all the CPUs
-			 * at once.  We have to preserve the order of the
-			 * devices on the bridges first though.
-			 */
-			while(atomic_read(&numstarted) != num_cpus);
-		}
-	}
-
-
-#ifdef LATER
-	Wait logic goes here.
-#endif
-	for (cnode = 0; cnode < numnodes; cnode++) {
-#if 0
-		if (cnodetocpu(cnode) == -1) {
-			printk("Initializing headless hub,cnode %d", cnode);
-			per_hub_init(cnode);
-		}
-#endif
-	}
-#if 0
-	cpu_io_setup();
-	init_mfhi_war();
-#endif
-	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 __init start_secondary(void)
-{
-	/* XXX Why do we need this empty definition at all?  */
-}
-#endif /* CONFIG_SMP */
-
-
-#define	rou_rflag	rou_flags
-
-void
-router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
-{
-	klrou_t *router;
-	lboard_t *brd;
-	int	port;
-
-	if (router_a->rou_rflag == 1)
-		return;
-
-	if (depth >= router_distance)
-		return;
-
-	router_a->rou_rflag = 1;
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		if (router_a->rou_port[port].port_nasid == INVALID_NASID)
-			continue;
-
-		brd = (lboard_t *)NODE_OFFSET_TO_K0(
-			router_a->rou_port[port].port_nasid,
-			router_a->rou_port[port].port_offset);
-
-		if (brd->brd_type == KLTYPE_ROUTER) {
-			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
-			if (router == router_b) {
-				if (depth < router_distance)
-					router_distance = depth;
-			}
-			else
-				router_recurse(router, router_b, depth + 1);
-		}
-	}
-
-	router_a->rou_rflag = 0;
-}
-
-int
-node_distance(nasid_t nasid_a, nasid_t nasid_b)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd, *dest_brd;
-	int port;
-	klrou_t *router, *router_a = NULL, *router_b = NULL;
-
-	/* Figure out which routers nodes in question are connected to */
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		if (nasid == -1) continue;
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-					KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
-			router->rou_rflag = 0;
-
-			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-				if (router->rou_port[port].port_nasid == INVALID_NASID)
-					continue;
-
-				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-					router->rou_port[port].port_nasid,
-					router->rou_port[port].port_offset);
-
-				if (dest_brd->brd_type == KLTYPE_IP27) {
-					if (dest_brd->brd_nasid == nasid_a)
-						router_a = router;
-					if (dest_brd->brd_nasid == nasid_b)
-						router_b = router;
-				}
-			}
-			
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-
-	if (router_a == NULL) {
-		printk("node_distance: router_a NULL\n");
-		return -1;
-	}
-	if (router_b == NULL) {
-		printk("node_distance: router_b NULL\n");
-		return -1;
-	}
-
-	if (nasid_a == nasid_b)
-		return 0;
-
-	if (router_a == router_b)
-		return 1;
-
-	router_distance = 100;
-	router_recurse(router_a, router_b, 2);
-
-	return router_distance;
-}
-
-void
-init_topology_matrix(void)
-{
-	nasid_t nasid, nasid2;
-	cnodeid_t row, col;
-
-	for (row = 0; row < MAX_COMPACT_NODES; row++)
-		for (col = 0; col < MAX_COMPACT_NODES; col++)
-			node_distances[row][col] = -1;
-
-	for (row = 0; row < numnodes; row++) {
-		nasid = COMPACT_TO_NASID_NODEID(row);
-		for (col = 0; col < numnodes; col++) {
-			nasid2 = COMPACT_TO_NASID_NODEID(col);
-			node_distances[row][col] = node_distance(nasid, nasid2);
-		}
-	}
-}
-
-void
-dump_topology(void)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd, *dest_brd;
-	int port;
-	int router_num = 0;
-	klrou_t *router;
-	cnodeid_t row, col;
-
-	printk("************** Topology ********************\n");
-
-	printk("    ");
-	for (col = 0; col < numnodes; col++)
-		printk("%02d ", col);
-	printk("\n");
-	for (row = 0; row < numnodes; row++) {
-		printk("%02d  ", row);
-		for (col = 0; col < numnodes; col++)
-			printk("%2d ", node_distances[row][col]);
-		printk("\n");
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		if (nasid == -1) continue;
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-					KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-			printk("Router %d:", router_num);
-			router_num++;
-
-			router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
-
-			for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-				if (router->rou_port[port].port_nasid == INVALID_NASID)
-					continue;
-
-				dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-					router->rou_port[port].port_nasid,
-					router->rou_port[port].port_offset);
-
-				if (dest_brd->brd_type == KLTYPE_IP27)
-					printk(" %d", dest_brd->brd_nasid);
-				if (dest_brd->brd_type == KLTYPE_ROUTER)
-					printk(" r");
-			}
-			printk("\n");
-			
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-#if 0
-#define		brd_widgetnum	brd_slot
-#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
-void
-dump_klcfg(void)
-{
-	cnodeid_t       cnode;
-	int i;
-	nasid_t         nasid;
-	lboard_t        *lbptr;
-	gda_t           *gdap;
-	
-	gdap = (gda_t *)GDA_ADDR(get_nasid());
-	if (gdap->g_magic != GDA_MAGIC) {
-		printk("dumpklcfg_cmd: Invalid GDA MAGIC\n");
-		return;
-	}
-
-	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
-		nasid = gdap->g_nasidtable[cnode];
-
-		if (nasid == INVALID_NASID)
-			continue;
-
-		printk("\nDumpping klconfig Nasid %d:\n", nasid);
-	
-		lbptr = KL_CONFIG_INFO(nasid);
-
-		while (lbptr) {
-			printk("    %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx",
-				"board name here", /* BOARD_NAME(lbptr->brd_type), */
-				lbptr->brd_nasid, lbptr->brd_module, 
-				lbptr->brd_widgetnum,
-				lbptr->brd_partition, 
-				(lbptr->brd_nic), lbptr);
-			if (lbptr->brd_flags & DUPLICATE_BOARD)
-				printk(" -D");
-			printk("\n");
-			for (i = 0; i < lbptr->brd_numcompts; i++) {
-				klinfo_t *kli;
-				kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]);                       
-				printk("        type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n", 
-					kli->struct_type, 
-					kli->flags,
-					kli->diagval,
-					kli->physid,
-					kli->virtid,
-					"comp. name here");
-					/* COMPONENT_NAME(kli->struct_type)); */
-			}
-			lbptr = KLCF_NEXT(lbptr);
-		}
-	}
-	printk("\n");
-
-	/* Useful to print router maps also */
-
-	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
-		klrou_t *kr;
-		int i;
-
-        	nasid = gdap->g_nasidtable[cnode];
-        	if (nasid == INVALID_NASID)
-            		continue;
-        	lbptr = KL_CONFIG_INFO(nasid);
-
-        	while (lbptr) {
-			
-			lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER);
-			if(!lbptr)
-				break;
-			if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) {
-				printk("%llx -> \n", lbptr->brd_nic);
-				kr = (klrou_t *)find_first_component(lbptr,
-					KLSTRUCT_ROU);
-				for (i = 1; i <= MAX_ROUTER_PORTS; i++) {
-					printk("[%d, %llx]; ",
-						kr->rou_port[i].port_nasid,
-						kr->rou_port[i].port_offset);
-				}
-				printk("\n");
-			}
-			lbptr = KLCF_NEXT(lbptr);
-        	}
-        	printk("\n");
-    	}
-
-	dump_topology();
-}
-#endif
-
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-irq-glue.S linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-irq-glue.S
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-irq-glue.S	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-irq-glue.S	Wed Dec 31 16:00:00 1969
@@ -1,64 +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.
- */
-#include <asm/asm.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-	.text
-	.set	noat
-	.align	5
-NESTED(ip27_irq, PT_SIZE, sp)
-	SAVE_ALL
-	CLI
-	.set	at
-
-	/* IP27 may signal interrupt which we're not interested in.
-	   Mask them out.  */
-	mfc0	s0, CP0_CAUSE
-	mfc0	t0, CP0_STATUS
-	and	s0, t0
-
-	/* First check for RT interrupt.  */
-	andi	a0, s0, CAUSEF_IP4
-	beqz	a0, 1f
-
-	/* Ok, a timer interrupt. */
-	move	a0, sp
-	jal	rt_timer_interrupt
-
-	j	ret_from_irq
-
-1:	andi	a0, s0, (CAUSEF_IP2 | CAUSEF_IP3)
-	beqz	a0, 1f
-
-	/* ... a device interrupt ...  */
-	move	a0, sp
-	jal	ip27_do_irq
-
-	j	ret_from_irq
-
-1:
-#if 1
-	mfc0	a1, CP0_STATUS
-	srl	a1, a1, 8
-	andi	a1, 0xff
-
-	mfc0	a2, CP0_CAUSE
-	srl	a2, a2, 8
-	andi	a2, 0xff
-
-	move	a3, s0
-	PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n")
-	ld	a1, PT_EPC(sp)
-0:	b	0b
-#endif
-
-	j	ret_from_irq
-	END(ip27_irq)
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-irq.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-irq.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-irq.c	Wed Dec 31 16:00:00 1969
@@ -1,487 +0,0 @@
-/*
- * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
- *
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- * Copyright (C) 1999 - 2001 Kanoj Sarcar
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.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_lock.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#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)
-#else
-#define DBG(x...)
-#endif
-
-/* These should die */
-unsigned char bus_to_wid[256];	/* widget id for linux pci bus */
-unsigned char bus_to_nid[256];	/* nasid for linux pci bus */
-unsigned char num_bridges;	/* number of bridges in the system */
-
-/*
- * 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.
- */
-
-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);
-
-/*
- * 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.
- */
-int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS];
-
-/*
- * use these macros to get the encoded nasid and widget id
- * from the irq value
- */
-#define IRQ_TO_BUS(i)			irq_to_bus[(i)]
-#define IRQ_TO_CPU(i)			bus_to_cpu[IRQ_TO_BUS(i)]
-#define NASID_FROM_PCI_IRQ(i)		bus_to_nid[IRQ_TO_BUS(i)]
-#define WID_FROM_PCI_IRQ(i)		bus_to_wid[IRQ_TO_BUS(i)]
-#define	SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
-
-static inline int alloc_level(cpuid_t cpunum, int irq)
-{
-	cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum);
-	int j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
-
-	while (++j < PERNODE_LEVELS) {
-		if (node_level_to_irq[nodenum][j] == -1) {
-			node_level_to_irq[nodenum][j] = irq;
-			return j;
-		}
-	}
-	printk("Cpu %ld flooded with devices\n", cpunum);
-	while(1);
-	return -1;
-}
-
-static inline int find_level(cpuid_t *cpunum, int irq)
-{
-	int j;
-	cnodeid_t nodenum = INVALID_CNODEID;
-
-	while (++nodenum < MAX_COMPACT_NODES) {
-		j = LEAST_LEVEL + 3;	/* resched & crosscall entries taken */
-		while (++j < PERNODE_LEVELS)
-			if (node_level_to_irq[nodenum][j] == irq) {
-				*cpunum = 0;	/* XXX Fixme */
-				return(j);
-			}
-	}
-	printk("Could not identify cpu/level for irq %d\n", irq);
-	while(1);
-	return(-1);
-}
-
-/*
- * Find first bit set
- */
-static int ms1bit(unsigned long x)
-{
-	int b = 0, 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;
-}
-
-/*
- * This code is unnecessarily complex, because we do SA_INTERRUPT
- * intr enabling. Basically, once we grab the set of intrs we need
- * to service, we must mask _all_ these interrupts; firstly, to make
- * sure the same intr does not intr again, causing recursion that 
- * can lead to stack overflow. Secondly, we can not just mask the
- * one intr we are do_IRQing, because the non-masked intrs in the
- * first set might intr again, causing multiple servicings of the
- * same intr. This effect is mostly seen for intercpu intrs.
- * Kanoj 05.13.00
- */
-void ip27_do_irq(struct pt_regs *regs)
-{
-	int irq, swlevel;
-	hubreg_t pend0, mask0;
-	cpuid_t thiscpu = smp_processor_id();
-	int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ?
-					PI_INT_MASK0_A : PI_INT_MASK0_B);
-
-	/* copied from Irix intpend0() */
-	while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) & 
-				(mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) {
-		pend0 &= mask0;		/* Pick intrs we should look at */
-		if (pend0) {
-			/* Prevent any of the picked intrs from recursing */
-			LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0));
-			do {
-				swlevel = ms1bit(pend0);
-				LOCAL_HUB_CLR_INTR(swlevel);
-				/* "map" swlevel to irq */
-				irq = LEVEL_TO_IRQ(thiscpu, swlevel);
-				do_IRQ(irq, regs);
-				/* clear bit in pend0 */
-				pend0 ^= 1ULL << swlevel;
-			} while(pend0);
-			/* Now allow the set of serviced intrs again */
-			LOCAL_HUB_S(pi_int_mask0, mask0);
-			LOCAL_HUB_L(PI_INT_PEND0);
-		}
-	}
-}
-
-
-/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(unsigned int irq)
-{
-	bridgereg_t device;
-	bridge_t *bridge;
-	int pin, swlevel;
-	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);
-
-	DBG("bridge_startup(): irq= 0x%x  pin=%d\n", irq, pin);
-	/*
-	 * "map" irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	swlevel = alloc_level(cpu, irq);
-	intr_connect_level(cpu, swlevel);
-
-	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8));
-	bridge->b_int_enable |= (1 << pin);
-	/* more stuff in int_enable reg */
-	bridge->b_int_enable |= 0x7ffffe00;
-
-	/*
-	 * XXX This only works if b_int_device is initialized to 0!
-	 * We program the bridge to have a 1:1 mapping between devices
-	 * (slots) and intr pins.
-	 */
-	device = bridge->b_int_device;
-	device |= (pin << (pin*3));
-	bridge->b_int_device = device;
-
-        bridge->b_widget.w_tflush;                      /* Flush */
-
-        return 0;       /* Never anything pending.  */
-}
-
-/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
-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);
-	pin = SLOT_FROM_PCI_IRQ(irq);
-
-	/*
-	 * map irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	swlevel = find_level(&cpu, irq);
-	intr_disconnect_level(cpu, swlevel);
-	LEVEL_TO_IRQ(cpu, swlevel) = -1;
-
-	bridge->b_int_enable &= ~(1 << pin);
-	bridge->b_widget.w_tflush;                      /* Flush */
-
-	return 0;       /* Never anything pending.  */
-}
-
-static inline void enable_bridge_irq(unsigned int irq)
-{
-	/* All the braindamage happens magically for us in ip27_do_irq */
-}
-
-static void disable_bridge_irq(unsigned int irq)
-{
-	/* All the braindamage happens magically for us in ip27_do_irq */
-}
-
-static void mask_and_ack_bridge_irq(unsigned int irq)
-{
-	/* All the braindamage happens magically for us in ip27_do_irq */
-}
-
-static void end_bridge_irq (unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_bridge_irq(irq);
-}
-
-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
-};
-
-void irq_debug(void)
-{
-	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));
-}
-
-void __init init_IRQ(void)
-{
-	int i;
-
-	set_except_vector(0, ip27_irq);
-
-	/*
-	 * Right now the bridge irq is our kitchen sink interrupt type
-	 */
-	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;
-	}
-}
-
-/*
- * 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,
-				hubreg_t **intpend_masks, int *ip)
-{
-	hub_intmasks_t *hub_intmasks;
-
-	hub_intmasks = &cpu_data[cpu].p_intmasks;
-	if (bit < N_INTPEND_BITS) {
-		*intpend_masks = hub_intmasks->intpend0_masks;
-		*ip = 0;
-		*new_bit = bit;
-	} else {
-		*intpend_masks = hub_intmasks->intpend1_masks;
-		*ip = 1;
-		*new_bit = bit - N_INTPEND_BITS;
-	}
-	return hub_intmasks;
-}
-
-int intr_connect_level(int cpu, int bit)
-{
-	int ip;
-	int slice = cputoslice(cpu);
-	volatile hubreg_t *mask_reg;
-	hubreg_t *intpend_masks;
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
-
-	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
-
-	/* Make sure it's not already pending when we connect it. */
-	REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS);
-
-	intpend_masks[0] |= (1ULL << (u64)bit);
-
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + 
-				PI_INT_MASK_OFFSET * slice);
-	} else {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + 
-				PI_INT_MASK_OFFSET * slice);
-	}
-	HUB_S(mask_reg, intpend_masks[0]);
-	return(0);
-}
-
-int intr_disconnect_level(int cpu, int bit)
-{
-	int ip;
-	int slice = cputoslice(cpu);
-	volatile hubreg_t *mask_reg;
-	hubreg_t *intpend_masks;
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu));
-
-	(void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip);
-	intpend_masks[0] &= ~(1ULL << (u64)bit);
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + 
-				PI_INT_MASK_OFFSET * slice);
-	} else {
-		mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + 
-				PI_INT_MASK_OFFSET * slice);
-	}
-	HUB_S(mask_reg, intpend_masks[0]);
-	return(0);
-}
-
-
-void handle_resched_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	/* 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)
-{
-#ifdef CONFIG_SMP
-#if (CPUS_PER_NODE == 2)
-	static int done = 0;
-
-	/*
-	 * This is a hack till we have a pernode irqlist. Currently,
-	 * just have the master cpu set up the handlers for the per
-	 * cpu irqs.
-	 */
-	if (done == 0) {
-		int j;
-
-		if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr, 
-							0, "resched", 0))
-			panic("intercpu intr unconnectible");
-		if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr, 
-							0, "resched", 0))
-			panic("intercpu intr unconnectible");
-		if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt,
-							0, "callfunc", 0))
-			panic("intercpu intr unconnectible");
-		if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt,
-							0, "callfunc", 0))
-			panic("intercpu intr unconnectible");
-
-		for (j = 0; j < PERNODE_LEVELS; j++)
-			LEVEL_TO_IRQ(0, j) = -1;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) = 
-							CPU_RESCHED_A_IRQ;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) = 
-							CPU_RESCHED_B_IRQ;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) = 
-							CPU_CALL_A_IRQ;
-		LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) = 
-							CPU_CALL_B_IRQ;
-		for (j = 1; j < MAX_COMPACT_NODES; j++)
-			memcpy(&node_level_to_irq[j][0], 
-			&node_level_to_irq[0][0], 
-			sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS);
-
-		done = 1;
-	}
-
-	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ + 
-							cputoslice(cpu)));
-	intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ +
-							cputoslice(cpu)));
-#else /* CPUS_PER_NODE */
-#error Must redefine this for more than 2 CPUS.
-#endif /* CPUS_PER_NODE */
-#endif /* CONFIG_SMP */
-}
-
-void install_tlbintr(int cpu)
-{
-#if 0
-	int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu);
-
-	intr_connect_level(cpu, intr_bit);
-#endif
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-klconfig.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-klconfig.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-klconfig.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-klconfig.c	Wed Dec 31 16:00:00 1969
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/param.h>
-#include <linux/timex.h>
-#include <linux/mm.h>		
-
-#include <asm/sn/klconfig.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/gda.h>
-
-klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			printk("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;		/* next component */
-	}
-
-	for (; index < KLCF_NUM_COMPS(brd); index++) {
-		kli = KLCF_COMP(brd, index);
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-cnodeid_t get_cpu_cnode(cpuid_t cpu)
-{
-	return CPUID_TO_COMPACT_NODEID(cpu);
-}
-
-klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
-{
-	lboard_t *brd;
-	klcpu_t *acpu;
-
-	if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
-		return (klcpu_t *)NULL;
-
-	if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
-		return (klcpu_t *)NULL;
-
-	do {
-		if ((acpu->cpu_info.physid) == slice)
-			return acpu;
-	} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, 
-								KLSTRUCT_CPU)));
-	return (klcpu_t *)NULL;
-}
-
-klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
-{
-	nasid_t nasid;
-	int slice;
-	klcpu_t *acpu;
-	gda_t *gdap = GDA;
-	cnodeid_t cnode;
-
-	if (!(cpu < MAXCPUS)) {
-		printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
-		return NULL;
-	}
-
-	cnode = get_cpu_cnode(cpu);
-	if (cnode == INVALID_CNODEID)
-		return NULL;
-
-	if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
-		return NULL;
-
-	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
-		acpu = nasid_slice_to_cpuinfo(nasid, slice);
-		if (acpu && acpu->cpu_info.virtid == cpu)
-			return acpu;
-	}
-	return NULL;
-}
-
-int get_cpu_slice(cpuid_t cpu)
-{
-	klcpu_t *acpu;
-
-	if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
-		return -1;
-	return acpu->cpu_info.physid;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-klnuma.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-klnuma.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-klnuma.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-klnuma.c	Wed Dec 31 16:00:00 1969
@@ -1,143 +0,0 @@
-/*
- * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
- * Copyright 2000 - 2001 Silicon Graphics, Inc.
- * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/mmzone.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-#include <asm/smp.h>
-#include <asm/sn/types.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/gda.h>
-#include <asm/mmzone.h>
-#include <asm/sn/klkernvars.h>
-#include <asm/sn/mapped_kernel.h>
-#include <asm/sn/sn_private.h>
-
-extern char _end;
-static cpumask_t ktext_repmask;
-
-/*
- * XXX - This needs to be much smarter about where it puts copies of the
- * kernel.  For example, we should never put a copy on a headless node,
- * and we should respect the topology of the machine.
- */
-void __init setup_replication_mask(int maxnodes)
-{
-	static int 	numa_kernel_replication_ratio;
-	cnodeid_t	cnode;
-
-	/* Set only the master cnode's bit.  The master cnode is always 0. */
-	CPUMASK_CLRALL(ktext_repmask);
-	CPUMASK_SETB(ktext_repmask, 0);
-
-	numa_kernel_replication_ratio = 0;
-#ifdef CONFIG_REPLICATE_KTEXT
-#ifndef CONFIG_MAPPED_KERNEL
-#error Kernel replication works with mapped kernel support. No calias support.
-#endif
-	numa_kernel_replication_ratio = 1;
-#endif
-
-	for (cnode = 1; cnode < numnodes; cnode++) {
-		/* See if this node should get a copy of the kernel */
-		if (numa_kernel_replication_ratio &&
-		    !(cnode % numa_kernel_replication_ratio)) {
-
-			/* Advertise that we have a copy of the kernel */
-			CPUMASK_SETB(ktext_repmask, cnode);
-		}
-	}
-
-	/* Set up a GDA pointer to the replication mask. */
-	GDA->g_ktext_repmask = &ktext_repmask;
-}
-
-
-static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
-{
-	kern_vars_t *kvp;
-	cnodeid_t client_cnode;
-
-	client_cnode = NASID_TO_COMPACT_NODEID(client_nasid);
-	
-	kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars);
-
-	KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
-
-	kvp->kv_magic = KV_MAGIC;
-
-	kvp->kv_ro_nasid = server_nasid;
-	kvp->kv_rw_nasid = master_nasid;
-	kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
-	kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
-	printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid);
-}
-
-/* XXX - When the BTE works, we should use it instead of this. */
-static __init void copy_kernel(nasid_t dest_nasid)
-{
-	extern char _stext, _etext;
-	unsigned long dest_kern_start, source_start, source_end, kern_size;
-
-	source_start = (unsigned long)&_stext;
-	source_end = (unsigned long)&_etext;
-	kern_size = source_end - source_start;
-
-	dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
-					    dest_nasid);
-	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
-}
-
-void __init replicate_kernel_text(int maxnodes)
-{
-	cnodeid_t cnode;
-	nasid_t client_nasid;
-	nasid_t server_nasid;
-
-	server_nasid = master_nasid;
-
-	/* Record where the master node should get its kernel text */
-	set_ktext_source(master_nasid, master_nasid);
-
-	for (cnode = 1; cnode < maxnodes; cnode++) {
-		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		/* Check if this node should get a copy of the kernel */
-		if (CPUMASK_TSTB(ktext_repmask, cnode)) {
-			server_nasid = client_nasid;
-			copy_kernel(server_nasid);
-		}
-
-		/* Record where this node should get its kernel text */
-		set_ktext_source(client_nasid, server_nasid);
-	}
-}
-
-/*
- * Return pfn of first free page of memory on a node. PROM may allocate
- * data structures on the first couple of pages of the first slot of each 
- * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
- */
-pfn_t node_getfirstfree(cnodeid_t cnode)
-{
-	unsigned long loadbase = CKSEG0;
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
-	unsigned long offset;
-
-#ifdef CONFIG_MAPPED_KERNEL
-	loadbase = CKSSEG + 16777216;
-#endif
-	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
-	if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode)))
-		return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
-	else
-		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> 
-								PAGE_SHIFT);
-}
-
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-memory.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-memory.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-memory.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-memory.c	Wed Dec 31 16:00:00 1969
@@ -1,344 +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 by Ralf Baechle
- * Copyright (C) 2000 by Silicon Graphics, Inc.
- *
- * On SGI IP27 the ARC memory configuration data is completly bogus but
- * alternate easier to use mechanisms are available.
- */
-#include <linux/init.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/swap.h>
-
-#include <asm/page.h>
-#include <asm/bootinfo.h>
-#include <asm/addrspace.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/arch.h>
-#include <asm/mmzone.h>
-
-/* ip27-klnuma.c   */
-extern pfn_t node_getfirstfree(cnodeid_t cnode);
-
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define SLOT_IGNORED	0xffff
-
-short slot_lastfilled_cache[MAX_COMPACT_NODES];
-unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS];
-static pfn_t numpages;
-
-plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES];
-bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES];
-
-int numa_debug(void)
-{
-	printk("NUMA debug\n");
-	*(int *)0 = 0;
-	return(0);
-}
-
-/*
- * Return the number of pages of memory provided by the given slot
- * on the specified node.
- */
-pfn_t slot_getsize(cnodeid_t node, int slot)
-{
-	return (pfn_t) slot_psize_cache[node][slot];
-}
-
-/*
- * Return highest slot filled
- */
-int node_getlastslot(cnodeid_t node)
-{
-	return (int) slot_lastfilled_cache[node];
-}
-
-/*
- * Return the pfn of the last free page of memory on a node.
- */
-pfn_t node_getmaxclick(cnodeid_t node)
-{
-	pfn_t	slot_psize;
-	int	slot;
-
-	/*
-	 * Start at the top slot. When we find a slot with memory in it,
-	 * that's the winner.
-	 */
-	for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) {
-		if ((slot_psize = slot_getsize(node, slot))) {
-			if (slot_psize == SLOT_IGNORED)
-				continue;
-			/* Return the basepfn + the slot size, minus 1. */
-			return slot_getbasepfn(node, slot) + slot_psize - 1;
-		}
-	}
-
-	/*
-	 * If there's no memory on the node, return 0. This is likely
-	 * to cause problems.
-	 */
-	return (pfn_t)0;
-}
-
-static pfn_t slot_psize_compute(cnodeid_t node, int slot)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klmembnk_t *banks;
-	unsigned long size;
-
-	nasid = COMPACT_TO_NASID_NODEID(node);
-	/* Find the node board */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
-	if (!brd)
-		return 0;
-
-	/* Get the memory bank structure */
-	banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
-	if (!banks)
-		return 0;
-
-	/* Size in _Megabytes_ */
-	size = (unsigned long)banks->membnk_bnksz[slot/4];
-
-	/* hack for 128 dimm banks */
-	if (size <= 128) {
-		if (slot%4 == 0) {
-			size <<= 20;		/* size in bytes */
-			return(size >> PAGE_SHIFT);
-		} else {
-			return 0;
-		}
-	} else {
-		size /= 4;
-		size <<= 20;
-		return(size >> PAGE_SHIFT);
-	}
-}
-
-pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
-{
-	cnodeid_t node;
-	int slot, numslots;
-	pfn_t num_pages = 0, slot_psize;
-	pfn_t slot0sz = 0, nodebytes;	/* Hack to detect problem configs */
-	int ignore;
-
-	for (node = 0; node < numnodes; node++) {
-		numslots = node_getnumslots(node);
-		ignore = nodebytes = 0;
-		for (slot = 0; slot < numslots; slot++) {
-			slot_psize = slot_psize_compute(node, slot);
-			if (slot == 0) slot0sz = slot_psize;
-			/* 
-			 * We need to refine the hack when we have replicated
-			 * kernel text.
-			 */
-			nodebytes += SLOT_SIZE;
-			if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
-						(slot0sz << PAGE_SHIFT))
-				ignore = 1;
-			if (ignore && slot_psize) {
-				printk("Ignoring slot %d onwards on node %d\n",
-								slot, node);
-				slot_psize_cache[node][slot] = SLOT_IGNORED;
-				slot = numslots;
-				continue;
-			}
-			num_pages += slot_psize;
-			slot_psize_cache[node][slot] = 
-					(unsigned short) slot_psize;
-			if (slot_psize)
-				slot_lastfilled_cache[node] = slot;
-		}
-	}
-	if (maxpmem)
-		return((maxpmem > num_pages) ? num_pages : maxpmem);
-	else
-		return num_pages;
-}
-
-/*
- * Currently, the intranode memory hole support assumes that each slot
- * contains at least 32 MBytes of memory. We assume all bootmem data
- * fits on the first slot.
- */
-void __init prom_meminit(void)
-{
-	extern void mlreset(void);
-	cnodeid_t node;
-	pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn;
-	unsigned long bootmap_size;
-	int node_datasz;
-
-	node_datasz = PFN_UP(sizeof(plat_pg_data_t));
-	mlreset();
-	numpages = szmem(0, 0);
-	for (node = (numnodes - 1); node >= 0; node--) {
-		slot_firstpfn = slot_getbasepfn(node, 0);
-		slot_lastpfn = slot_firstpfn + slot_getsize(node, 0);
-		slot_freepfn = node_getfirstfree(node);
-		/* Foll line hack for non discontigmem; remove once discontigmem
-		 * becomes the default. */
-		max_low_pfn = (slot_lastpfn - slot_firstpfn);
-
-		/*
-		 * Allocate the node data structure on the node first.
-		 */
-		plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \
-							<< PAGE_SHIFT));
-		NODE_DATA(node)->bdata = plat_node_bdata + node;
-		slot_freepfn += node_datasz;
-	  	bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, 
-						slot_firstpfn, slot_lastpfn);
-		free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, 
-				(slot_lastpfn - slot_firstpfn) << PAGE_SHIFT);
-		reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
-		  ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size);
-	}
-	printk("Total memory probed : 0x%lx pages\n", numpages);
-}
-
-int __init page_is_ram(unsigned long pagenr)
-{
-        return 1;
-}
-
-void __init
-prom_free_prom_memory (void)
-{
-	/* We got nothing to free here ...  */
-}
-
-#ifdef CONFIG_DISCONTIGMEM
-
-static pfn_t pagenr = 0;
-
-void __init paging_init(void)
-{
-	pmd_t *pmd = kpmdtbl;
-	pte_t *pte = kptbl;
-
-	cnodeid_t node;
-	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-	int i;
-
-	/* Initialize the entire pgd.  */
-	pgd_init((unsigned long)swapper_pg_dir);
-	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
-	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
-
-	/* This is for vmalloc  */
-	memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER);
-	memset((void *)kpmdtbl, 0, PAGE_SIZE);
-	pgd_set(swapper_pg_dir, kpmdtbl);
-	for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE)
-		pmd_val(*pmd) = (unsigned long)pte;
-
-	for (node = 0; node < numnodes; node++) {
-		pfn_t start_pfn = slot_getbasepfn(node, 0);
-		pfn_t end_pfn = node_getmaxclick(node);
-
-		zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
-		free_area_init_node(node, NODE_DATA(node), 0, zones_size, 
-						start_pfn << PAGE_SHIFT, 0);
-		if ((PLAT_NODE_DATA_STARTNR(node) + 
-					PLAT_NODE_DATA_SIZE(node)) > pagenr)
-			pagenr = PLAT_NODE_DATA_STARTNR(node) +
-					PLAT_NODE_DATA_SIZE(node);
-	}
-}
-
-void __init mem_init(void)
-{
-	extern char _stext, _etext, _fdata, _edata;
-	extern char __init_begin, __init_end;
-	extern unsigned long totalram_pages;
-	extern unsigned long setup_zero_pages(void);
-	cnodeid_t nid;
-	unsigned long tmp;
-	unsigned long codesize, datasize, initsize;
-	int slot, numslots;
-	struct page *pg, *pslot;
-	pfn_t pgnr;
-
-	num_physpages = numpages;	/* memory already sized by szmem */
-	max_mapnr = pagenr;		/* already found during paging_init */
-	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
-
-	for (nid = 0; nid < numnodes; nid++) {
-
-		/*
-		 * Hack till free_area_init_core() zeroes free_pages
-		 */
-		for (tmp = 0; tmp < MAX_NR_ZONES; tmp++)
-			PLAT_NODE_DATA(nid)->gendata.node_zones[tmp].free_pages=0;
-		/*
-	 	 * This will free up the bootmem, ie, slot 0 memory.
-	 	 */
-		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
-
-		/*
-		 * We need to manually do the other slots.
-		 */
-		pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0);
-		pgnr = PLAT_NODE_DATA_STARTNR(nid) + slot_getsize(nid, 0);
-		numslots = node_getlastslot(nid);
-		for (slot = 1; slot <= numslots; slot++) {
-			pslot = NODE_DATA(nid)->node_mem_map + 
-			   slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0);
-
-			/*
-			 * Mark holes in previous slot. May also want to
-			 * free up the pages that hold the memmap entries.
-			 */
-			while (pg < pslot) {
-				pg++; pgnr++;
-			}
-
-			/*
-			 * Free valid memory in current slot.
-			 */
-			pslot += slot_getsize(nid, slot);
-			while (pg < pslot) {
-				if (!page_is_ram(pgnr))
-					continue;
-				ClearPageReserved(pg);
-				atomic_set(&pg->count, 1);
-				__free_page(pg);
-				totalram_pages++;
-				pg++; pgnr++;
-			}
-		}
-	}
-
-	totalram_pages -= setup_zero_pages();	/* This comes from node 0 */
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	tmp = (unsigned long) nr_free_pages();
-	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
-		"%ldk data, %ldk init)\n",
-		tmp << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		(num_physpages - tmp) << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10);
-}
-
-#endif /* CONFIG_DISCONTIGMEM */
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-nmi.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-nmi.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-nmi.c	Tue Nov 28 21:42:04 2000
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-nmi.c	Wed Dec 31 16:00:00 1969
@@ -1,168 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/mmzone.h>
-#include <linux/spinlock.h>
-#include <linux/smp.h>
-#include <asm/atomic.h>
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/nmi.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn0/hub.h>
-
-#if 0
-#define NODE_NUM_CPUS(n)	CNODE_NUM_CPUS(n)
-#else
-#define NODE_NUM_CPUS(n)	CPUS_PER_NODE
-#endif
-
-#define CNODEID_NONE (cnodeid_t)-1
-#define enter_panic_mode()	spin_lock(&nmi_lock)
-
-typedef unsigned long machreg_t;
-
-spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * Lets see what else we need to do here. Set up sp, gp?
- */
-void nmi_dump(void)
-{
-	void cont_nmi_dump(void);
-
-	cont_nmi_dump();
-}
-
-void install_cpu_nmi_handler(int slice)
-{
-	nmi_t *nmi_addr;
-
-	nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
-	if (nmi_addr->call_addr)
-		return;
-	nmi_addr->magic = NMI_MAGIC;
-	nmi_addr->call_addr = (void *)nmi_dump;
-	nmi_addr->call_addr_c =
-		(void *)(~((unsigned long)(nmi_addr->call_addr)));
-	nmi_addr->call_parm = 0;
-}
-
-/*
- * Copy the cpu registers which have been saved in the IP27prom format
- * into the eframe format for the node under consideration.
- */
-
-void
-nmi_cpu_eframe_save(nasid_t nasid,
-		    int	    slice)
-{
-	int 		i, numberof_nmi_cpu_regs;
-	machreg_t	*prom_format;
-
-	/* Get the total number of registers being saved by the prom */
-	numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t);
-
-	/* Get the pointer to the current cpu's register set. */
-	prom_format = 
-	    (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
-			  slice * IP27_NMI_KREGS_CPU_SIZE);
-
-	printk("NMI nasid %d: slice %d\n", nasid, slice);
-	for (i = 0; i < numberof_nmi_cpu_regs; i++)
-		printk("0x%lx  ", prom_format[i]);
-	printk("\n\n");
-}	
-
-/*
- * Copy the cpu registers which have been saved in the IP27prom format
- * into the eframe format for the node under consideration.
- */
-void
-nmi_node_eframe_save(cnodeid_t  cnode)
-{
-	int		cpu;
-	nasid_t		nasid;
-
-	/* Make sure that we have a valid node */
-	if (cnode == CNODEID_NONE)
-		return;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	if (nasid == INVALID_NASID)
-		return;
-
-	/* Save the registers into eframe for each cpu */
-	for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++) 
-		nmi_cpu_eframe_save(nasid, cpu);
-}
-
-/*
- * Save the nmi cpu registers for all cpus in the system.
- */
-void
-nmi_eframes_save(void)
-{
-	cnodeid_t	cnode;
-
-	for(cnode = 0 ; cnode < numnodes; cnode++) 
-		nmi_node_eframe_save(cnode);
-}
-
-void
-cont_nmi_dump(void)
-{
-#ifndef REAL_NMI_SIGNAL
-	static atomic_t nmied_cpus = ATOMIC_INIT(0);
-
-	atomic_inc(&nmied_cpus);
-#endif
-	/* 
-	 * Use enter_panic_mode to allow only 1 cpu to proceed
-	 */
-	enter_panic_mode();
-
-#ifdef REAL_NMI_SIGNAL
-	/*
-	 * Wait up to 15 seconds for the other cpus to respond to the NMI.
-	 * If a cpu has not responded after 10 sec, send it 1 additional NMI.
-	 * This is for 2 reasons:
-	 *	- sometimes a MMSC fail to NMI all cpus.
-	 *	- on 512p SN0 system, the MMSC will only send NMIs to
-	 *	  half the cpus. Unfortunately, we dont know which cpus may be
-	 *	  NMIed - it depends on how the site chooses to configure.
-	 * 
-	 * Note: it has been measure that it takes the MMSC up to 2.3 secs to
-	 * send NMIs to all cpus on a 256p system.
-	 */
-	for (i=0; i < 1500; i++) {
-		for (node=0; node < numnodes; node++)
-			if (NODEPDA(node)->dump_count == 0)
-				break;
-		if (node == numnodes)
-			break;
-		if (i == 1000) {
-			for (node=0; node < numnodes; node++)
-				if (NODEPDA(node)->dump_count == 0) {
-					cpu = CNODE_TO_CPU_BASE(node);
-					for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
-						CPUMASK_SETB(nmied_cpus, cpu);
-						/* 
-						 * cputonasid, cputoslice
-						 * needs kernel cpuid
-						 */
-						SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
-					}
-				}
-					
-		}
-		udelay(10000);
-	}
-#else
-	while (atomic_read(&nmied_cpus) != smp_num_cpus);
-#endif
-
-	/*
-	 * Save the nmi cpu registers for all cpu in the eframe format.
-	 */
-	nmi_eframes_save();
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-pci-dma.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-pci-dma.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-pci-dma.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-pci-dma.c	Wed Dec 31 16:00:00 1969
@@ -1,150 +0,0 @@
-/*
- * Dynamic DMA mapping support.
- *
- * On the Origin there is dynamic DMA address translation for all PCI DMA.
- * However we don't use this facility yet but rely on the 2gb direct
- * mapped DMA window for PCI64.  So consistent alloc/free are merely page
- * allocation/freeing.  The rest of the dynamic DMA mapping interface is
- * implemented in <asm/pci.h>.  So this code will fail with more than
- * 2gb of memory.
- */
-#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;
-	int order = get_order(size);
-
-	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
-		gfp |= GFP_DMA;
-	ret = (void *)__get_free_pages(gfp, order);
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = (bus_to_baddr[hwdev->bus->number] | __pa(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));
-}
-
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * 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.
- */
-dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
-                          int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	return (bus_to_baddr[hwdev->bus->number] | __pa(ptr));
-}
-
-/*
- * Unmap a single streaming mode DMA translation.  The dma_addr and size
- * must match what was provided for in a previous pci_map_single call.  All
- * other usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guarenteed to see
- * whatever the device wrote there.
- */
-void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-                     size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		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
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-               int direction)
-{
-	int i;
-
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Make sure that gcc doesn't leave the empty loop body.  */
-	for (i = 0; i < nents; i++, sg++) {
-		sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address));
-	}
-
-	return nents;
-}
-
-/*
- * Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
-                  int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* Nothing to do */
-}
-
-/*
- * Make physical memory consistent for a single
- * streaming mode DMA translation after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, the
- * device again owns the buffer.
- */
-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();
-}
-
-/*
- * Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single but for a scatter-gather list,
- * same rules and usage.
- */
-void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-                     int nelems, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-		BUG();
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-pci.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-pci.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-pci.c	Wed Dec 31 16:00:00 1969
@@ -1,428 +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, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <asm/sn/arch.h>
-#include <asm/pci/bridge.h>
-#include <asm/paccess.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hub.h>
-
-/*
- * Max #PCI busses we can handle; ie, max #PCI bridges.
- */
-#define MAX_PCI_BUSSES		40
-
-/*
- * Max #PCI devices (like scsi controllers) we handle on a bus.
- */
-#define MAX_DEVICES_PER_PCIBUS	8
-
-/*
- * No locking needed until PCI initialization is done parallely.
- */
-int irqstore[MAX_PCI_BUSSES][MAX_DEVICES_PER_PCIBUS];
-int lastirq = BASE_PCI_IRQ;
-
-/*
- * Translate from irq to software PCI bus number and PCI slot.
- */
-int irq_to_bus[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
-int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
-
-/*
- * The Bridge ASIC supports both type 0 and type 1 access.  Type 1 is
- * not really documented, so right now I can't write code which uses it.
- * Therefore we use type 0 accesses for now even though they won't work
- * correcly for PCI-to-PCI bridges.
- */
-#define CF0_READ_PCI_CFG(dev,where,value,bm,mask)			\
-do {									\
-	bridge_t *bridge;                                               \
-	int slot = PCI_SLOT(dev->devfn);				\
-	int fn = PCI_FUNC(dev->devfn);					\
-	volatile u32 *addr;						\
-	u32 cf, __bit;							\
-	unsigned int bus_id = (unsigned) dev->bus->number;              \
-									\
-	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
-                                             bus_to_wid[bus_id]);       \
-                                                                        \
-	if (dev->vendor == PCI_VENDOR_ID_SGI				\
-	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
-	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) {	\
-		*value = 0;						\
-		return PCIBIOS_SUCCESSFUL;				\
-	}								\
-									\
-	__bit = (((where) & (bm)) << 3);				\
-	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
-	if (get_dbe(cf, addr))						\
-		return PCIBIOS_DEVICE_NOT_FOUND;			\
-	*value = (cf >> __bit) & (mask);				\
-	return PCIBIOS_SUCCESSFUL;					\
-} while (0)
-
-static int
-pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value)
-{
-	CF0_READ_PCI_CFG(dev,where,value,3,0xff);
-}
-
-static int
-pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value)
-{
-	CF0_READ_PCI_CFG(dev,where,value,2,0xffff);
-}
-
-static int
-pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value)
-{
-	CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff);
-}
-
-#define CF0_WRITE_PCI_CFG(dev,where,value,bm,mask)			\
-do {									\
-	bridge_t *bridge;                                               \
-	int slot = PCI_SLOT(dev->devfn);				\
-	int fn = PCI_FUNC(dev->devfn);					\
-	volatile u32 *addr;						\
-	u32 cf, __bit;							\
-	unsigned int bus_id = (unsigned) dev->bus->number;              \
-									\
-	bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],        \
-                                             bus_to_wid[bus_id]);       \
-                                                                        \
-	if (dev->vendor == PCI_VENDOR_ID_SGI				\
-	    && dev->device == PCI_DEVICE_ID_SGI_IOC3			\
-	    && ((where >= 0x14 && where < 0x40) || (where >= 0x48)))	\
-		return PCIBIOS_SUCCESSFUL;				\
-									\
-	__bit = (((where) & (bm)) << 3);				\
-	addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];	\
-	if (get_dbe(cf, addr))						\
-		return PCIBIOS_DEVICE_NOT_FOUND;			\
-	cf &= (~mask);							\
-	cf |= (value);							\
-	put_dbe(cf, addr);						\
-	return PCIBIOS_SUCCESSFUL;					\
-} while (0)
-
-static int
-pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value)
-{
-	CF0_WRITE_PCI_CFG(dev,where,value,3,0xff);
-}
-
-static int
-pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value)
-{
-	CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff);
-}
-
-static int
-pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value)
-{
-	CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff);
-}
-
-
-static struct pci_ops bridge_pci_ops = {
-	pci_conf0_read_config_byte,
-	pci_conf0_read_config_word,
-	pci_conf0_read_config_dword,
-	pci_conf0_write_config_byte,
-	pci_conf0_write_config_word,
-	pci_conf0_write_config_dword
-};
-
-void __init pcibios_init(void)
-{
-	struct pci_ops *ops = &bridge_pci_ops;
-	int	i;
-
-	ioport_resource.end = ~0UL;
-	iomem_resource.end = ~0UL;
-
-	for (i=0; i<num_bridges; i++) {
-		printk("PCI: Probing PCI hardware on host bus %2d.\n", i);
-		pci_scan_bus(i, ops, NULL);
-	}
-}
-
-static inline u8
-bridge_swizzle(u8 pin, u8 slot) 
-{
-	return (((pin-1) + slot) % 4) + 1;
-}
-
-static u8 __init
-pci_swizzle(struct pci_dev *dev, u8 *pinp)
-{
-	u8 pin = *pinp;
-
-	while (dev->bus->self) {	/* Move up the chain of bridges. */
-		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-		dev = dev->bus->self;
-	}
-	*pinp = pin;
-
-	return PCI_SLOT(dev->devfn);
-}
-
-/*
- * All observed requests have pin == 1. We could have a global here, that
- * gets incremented and returned every time - unfortunately, pci_map_irq
- * may be called on the same device over and over, and need to return the
- * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7]. 
- *
- * A given PCI device, in general, should be able to intr any of the cpus
- * on any one of the hubs connected to its xbow.
- */
-static int __init
-pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	if ((dev->bus->number >= MAX_PCI_BUSSES)
-	    || (pin != 1)
-	    || (slot >= MAX_DEVICES_PER_PCIBUS))
-		panic("Increase supported PCI busses %d,%d,%d",
-		      dev->bus->number, slot, pin);
-
-	/*
-	 * Already assigned? Then return previously assigned value ...
-	 */
-	if (irqstore[dev->bus->number][slot])
-		return irqstore[dev->bus->number][slot];
-
-	irq_to_bus[lastirq] = dev->bus->number;
-	irq_to_slot[lastirq] = slot;
-	irqstore[dev->bus->number][slot] = lastirq;
-	lastirq++;
-	return lastirq - 1;
-}
-
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-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)
-{
-	pci_fixup_irqs(pci_swizzle, pci_map_irq);
-}
-
-void __init
-pcibios_fixup_pbus_ranges(struct pci_bus * bus,
-                          struct pbus_set_ranges_data * ranges)
-{
-	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;
-}
-
-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)
-{
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
-	return 0;
-}
-
-char * __init
-pcibios_setup(char *str)
-{
-	/* Nothing to do for now.  */
-
-	return str;
-}
-
-/*
- * Device might live on a subordinate PCI bus.  XXX Walk up the chain of buses
- * to find the slot number in sense of the bridge device register.
- * XXX This also means multiple devices might rely on conflicting bridge
- * settings.
- */
-
-static void __init
-pci_disable_swapping(struct pci_dev *dev)
-{
-	unsigned int bus_id = (unsigned) dev->bus->number;
-	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-	                                               bus_to_wid[bus_id]);
-	int		slot = PCI_SLOT(dev->devfn);
-
-	/* Turn off byte swapping */
-	bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
-	bridge->b_widget.w_tflush;		/* Flush */
-}
-
-static void __init
-pci_enable_swapping(struct pci_dev *dev)
-{
-	unsigned int bus_id = (unsigned) dev->bus->number;
-	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-	                                               bus_to_wid[bus_id]);
-	int		slot = PCI_SLOT(dev->devfn);
-
-	/* Turn on byte swapping */
-	bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
-	bridge->b_widget.w_tflush;		/* Flush */
-}
-
-static void __init
-pci_fixup_ioc3(struct pci_dev *d)
-{
-	unsigned long bus_id = (unsigned) d->bus->number;
-
-	printk("PCI: Fixing base addresses for IOC3 device %s\n", d->slot_name);
-
-	d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]);
-	d->resource[0].end   |= NODE_OFFSET(bus_to_nid[bus_id]);
-
-	pci_disable_swapping(d);
-}
-
-static void __init
-pci_fixup_isp1020(struct pci_dev *d)
-{
-	unsigned short command;
-
-	d->resource[0].start |= ((unsigned long)(bus_to_nid[d->bus->number])<<32);
-	printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name);
-
-	/*
-	 * Configure device to allow bus mastering, i/o and memory mapping. 
-	 * Older qlogicisp driver expects to have the IO space enable 
-	 * bit set. Things stop working if we program the controllers as not 
-	 * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
-	 */
-
-	pci_set_master(d);
-	pci_read_config_word(d, PCI_COMMAND, &command);
-	command |= PCI_COMMAND_MEMORY;
-	command |= PCI_COMMAND_IO;
-	pci_write_config_word(d, PCI_COMMAND, command);
-	d->resource[1].flags |= 1;
-
-	pci_enable_swapping(d);
-}
-
-static void __init
-pci_fixup_isp2x00(struct pci_dev *d)
-{
-	unsigned int bus_id = (unsigned) d->bus->number;
-	bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id],
-				     bus_to_wid[bus_id]);
-	bridgereg_t 	devreg;
-	int		i;
-	int		slot = PCI_SLOT(d->devfn);
-	unsigned int	start;
-	unsigned short command;
-
-	printk("PCI: Fixing isp2x00 in [bus:slot.fn] %s\n", d->slot_name);
-
-	/* set the resource struct for this device */
-	start = (u32) (u64)bridge;	/* yes, we want to lose the upper 32 bits here */
-	start |= BRIDGE_DEVIO(slot);
-
-	d->resource[0].start = start;
-	d->resource[0].end = d->resource[0].start + 0xff;
-	d->resource[0].flags = IORESOURCE_IO;
-
-	d->resource[1].start = start;
-	d->resource[1].end = d->resource[0].start + 0xfff;
-	d->resource[1].flags = IORESOURCE_MEM;
-
-	/*
-	 * set the bridge device(x) reg for this device
-	 */
-	devreg = bridge->b_device[slot].reg;
-	/* point device(x) to it appropriate small window */
-	devreg &= ~BRIDGE_DEV_OFF_MASK;
-	devreg |= (start >> 20) & BRIDGE_DEV_OFF_MASK;
-	bridge->b_device[slot].reg = devreg;
-
-	pci_enable_swapping(d);
-
-	/* set card's base addr reg */
-	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x500001);
-	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0x8b00000);
-	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, 0x8b20000);
-
-	/* I got these from booting irix on system...*/
-	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x200001);
-	//pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0xf800000);
-	pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS,   0x10200000);
-
-	pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, start);
-	//pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, (start | 0x20000));
-
-	/* set cache line size */
-	pci_conf0_write_config_dword(d, PCI_CACHE_LINE_SIZE, 0xf080);
-
-	/* set pci bus timeout */
-	bridge->b_bus_timeout |= BRIDGE_BUS_PCI_RETRY_HLD(0x3);
-	bridge->b_wid_tflush;
-	printk("PCI: bridge bus timeout= 0x%x \n", bridge->b_bus_timeout);
-
-	/* set host error field */
-	bridge->b_int_host_err = 0x44;
-	bridge->b_wid_tflush;
-
-	bridge->b_wid_tflush;   	/* wait until Bridge PIO complete */
-	for (i=0; i<8; i++)
-		printk("PCI: device(%d)= 0x%x\n",i,bridge->b_device[i].reg);
-
-	/* configure device to allow bus mastering, i/o and memory mapping */
-	pci_set_master(d);
-	pci_read_config_word(d, PCI_COMMAND, &command);
-	command |= PCI_COMMAND_MEMORY;
-	command |= PCI_COMMAND_IO;
-	pci_write_config_word(d, PCI_COMMAND, command);
-	/*d->resource[1].flags |= 1;*/
-}
-
-struct pci_fixup pcibios_fixups[] = {
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
-	  pci_fixup_ioc3 },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
-	  pci_fixup_isp1020 },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
-	  pci_fixup_isp2x00 },
-	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
-	  pci_fixup_isp2x00 },
-	{ 0 }
-};
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-reset.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-reset.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-reset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-reset.c	Wed Dec 31 16:00:00 1969
@@ -1,80 +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 IP27.
- *
- * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#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>
-#include <asm/sn/arch.h>
-#include <asm/sn/gda.h>
-#include <asm/sn/sn0/hub.h>
-
-void machine_restart(char *command) __attribute__((noreturn));
-void machine_halt(void) __attribute__((noreturn));
-void machine_power_off(void) __attribute__((noreturn));
-
-#define noreturn while(1);				/* Silence gcc.  */
-
-/* XXX How to pass the reboot command to the firmware??? */
-static void ip27_machine_restart(char *command)
-{
-#if 0
-	int i;
-#endif
-
-	printk("Reboot started from CPU %d\n", smp_processor_id());
-#ifdef CONFIG_SMP
-	smp_send_stop();
-#endif
-#if 0
-	for (i = 0; i < numnodes; i++)
-		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, 
-							PROMOP_REBOOT);
-#else
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-#endif
-	noreturn;
-}
-
-static void ip27_machine_halt(void)
-{
-	int i;
-
-#ifdef CONFIG_SMP
-	smp_send_stop();
-#endif
-	for (i = 0; i < numnodes; i++)
-		REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, 
-							PROMOP_RESTART);
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-	noreturn;
-}
-
-static void ip27_machine_power_off(void)
-{
-	/* To do ...  */
-	noreturn;
-}
-
-void ip27_reboot_setup(void)
-{
-	_machine_restart = ip27_machine_restart;
-	_machine_halt = ip27_machine_halt;
-	_machine_power_off = ip27_machine_power_off;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-rtc.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-rtc.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-rtc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-rtc.c	Wed Dec 31 16:00:00 1969
@@ -1,334 +0,0 @@
-/*
- *	Driver for the SGS-Thomson M48T35 Timekeeper RAM chip
- *
- *	Real Time Clock interface for Linux	
- *
- *	TODO: Implement periodic interrupts.
- *
- *	Copyright (C) 2000 Silicon Graphics, Inc.
- *	Written by Ulf Carlsson (ulfc@engr.sgi.com)
- *
- *	Based on code written by Paul Gortmaker.
- *
- *	This driver allows use of the real time clock (built into
- *	nearly all computers) from user space. It exports the /dev/rtc
- *	interface supporting various ioctl() and also the /proc/rtc
- *	pseudo-file for status 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.
- *
- */
-
-#define RTC_VERSION		"1.09b"
-
-#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/rtc.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
-
-#include <asm/m48t35.h>
-#include <asm/sn/ioc3.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hub.h>
-
-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);
-
-static void get_rtc_time(struct rtc_time *rtc_tm);
-
-/*
- *	Bits in rtc_status. (6 bits of room for future expansion)
- */
-
-#define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
-#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;
-
-/*
- *	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 = 1970;	/* year corresponding to 0x00	*/
-
-static const unsigned char days_in_mo[] = 
-{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-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	*/
-	{
-		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;
-		unsigned long flags;
-			
-		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 + 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 -= epoch) > 255)    /* They are unsigned */
-			return -EINVAL;
-
-		save_flags(flags);
-		cli();
-		if (yrs > 169) {
-			restore_flags(flags);
-			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);
-
-		rtc->control &= ~M48T35_RTC_SET;
-		rtc->year = yrs;
-		rtc->month = mon;
-		rtc->date = day;
-		rtc->hour = hrs;
-		rtc->min = min;
-		rtc->sec = sec;
-		rtc->control &= ~M48T35_RTC_SET;
-
-		restore_flags(flags);
-		return 0;
-	}
-	default:
-		return -EINVAL;
-	}
-	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
-}
-
-/*
- *	We enforce only one user at a time here with the open/close.
- *	Also clear the previous interrupt data on an open, and clean
- *	up things on a close.
- */
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
-	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;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
-	/*
-	 * Turn off all interrupts once the device is no longer
-	 * in use, and clear the data.
-	 */
-
-	spin_lock(rtc_status_lock);
-	rtc_status &= ~RTC_IS_OPEN;
-	spin_unlock(rtc_status_lock);
-
-	return 0;
-}
-
-/*
- *	The various file operations we support.
- */
-
-static struct file_operations rtc_fops = {
-	owner:		THIS_MODULE,
-	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)
-{
-	unsigned long flags;
-	nasid_t nid;
-
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)
-	    KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0;
-
-	printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
-	if (misc_register(&rtc_dev))
-		return -ENODEV;
-	create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL);
-
-	save_flags(flags);
-	cli();
-	restore_flags(flags);
-	rtc_freq = 1024;
-	return 0;
-}
-
-static void __exit rtc_exit (void)
-{
-	/* interrupts and timer disabled at this point by rtc_release */
-
-	remove_proc_entry ("rtc", NULL);
-	misc_deregister(&rtc_dev);
-}
-
-module_init(rtc_init);
-module_exit(rtc_exit);
-EXPORT_NO_SYMBOLS;
-
-/*
- *	Info exported via "/proc/rtc".
- */
-
-static int rtc_get_status(char *buf)
-{
-	char *p;
-	struct rtc_time tm;
-
-	/*
-	 * Just emulate the standard /proc/rtc
-	 */
-
-	p = buf;
-
-	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"
-		     "24hr\t\t: yes\n",
-		     tm.tm_hour, tm.tm_min, tm.tm_sec,
-		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
-
-	return  p - buf;
-}
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
-{
-        int len = rtc_get_status(page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
-}
-
-static void get_rtc_time(struct rtc_time *rtc_tm)
-{
-
-	unsigned long flags;
-
-	/*
-	 * Do we need to wait for the last update to finish?
-	 */
-
-	/*
-	 * Only the values that we read from the RTC are set. We leave
-	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
-	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
-	 * by the RTC when initially set to a non-zero value.
-	 */
-	save_flags(flags);
-	cli();
-        rtc->control |= M48T35_RTC_READ;
-	rtc_tm->tm_sec = rtc->sec;
-	rtc_tm->tm_min = rtc->min;
-	rtc_tm->tm_hour = rtc->hour;
-	rtc_tm->tm_mday = rtc->date;
-	rtc_tm->tm_mon = rtc->month;
-	rtc_tm->tm_year = rtc->year;
-	rtc->control &= ~M48T35_RTC_READ;
-	restore_flags(flags);
-
-	BCD_TO_BIN(rtc_tm->tm_sec);
-	BCD_TO_BIN(rtc_tm->tm_min);
-	BCD_TO_BIN(rtc_tm->tm_hour);
-	BCD_TO_BIN(rtc_tm->tm_mday);
-	BCD_TO_BIN(rtc_tm->tm_mon);
-	BCD_TO_BIN(rtc_tm->tm_year);
-
-	/*
-	 * Account for differences between how the RTC uses the values
-	 * and how they are defined in a struct rtc_time;
-	 */
-	if ((rtc_tm->tm_year += (epoch - 1900)) <= 69)
-		rtc_tm->tm_year += 100;
-
-	rtc_tm->tm_mon--;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-setup.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-setup.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-setup.c	Wed Dec 31 16:00:00 1969
@@ -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.
- *
- * SGI IP27 specific setup.
- *
- * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#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>
-#include <asm/sn/sn0/hubni.h>
-#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>
-#include <asm/pci/bridge.h>
-#include <asm/paccess.h>
-#include <asm/sn/sn0/ip27.h>
-
-/* Check against user dumbness.  */
-#ifdef CONFIG_VT
-#error CONFIG_VT not allowed for IP27.
-#endif
-
-#undef DEBUG_SETUP
-#ifdef DEBUG_SETUP
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/*
- * get_nasid() returns the physical node id number of the caller.
- */
-nasid_t
-get_nasid(void)
-{
-	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
-	                 >> NSRI_NODEID_SHFT);
-}
-
-/* Extracted from the IOC3 meta driver.  FIXME.  */
-static inline void ioc3_sio_init(void)
-{
-	struct ioc3 *ioc3;
-	nasid_t nid;
-        long loops;
-
-	nid = get_nasid();
-	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
-
-	ioc3->sscr_a = 0;			/* PIO mode for uarta.  */
-	ioc3->sscr_b = 0;			/* PIO mode for uartb.  */
-	ioc3->sio_iec = ~0;
-	ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
-
-	loops=1000000; while(loops--);
-	ioc3->sregs.uarta.iu_fcr = 0;
-	ioc3->sregs.uartb.iu_fcr = 0;
-	loops=1000000; while(loops--);
-}
-
-static inline void ioc3_eth_init(void)
-{
-	struct ioc3 *ioc3;
-	nasid_t nid;
-
-	nid = get_nasid();
-	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
-
-	ioc3->eier = 0;
-}
-
-/* Try to catch kernel missconfigurations and give user an indication what
-   option to select.  */
-static void __init verify_mode(void)
-{
-	int n_mode;
-
-	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
-	printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
-#ifdef CONFIG_SGI_SN0_N_MODE
-	if (!n_mode)
-		panic("Kernel compiled for M mode.");
-#else
-	if (n_mode)
-		panic("Kernel compiled for N mode.");
-#endif
-}
-
-#define XBOW_WIDGET_PART_NUM    0x0
-#define XXBOW_WIDGET_PART_NUM   0xd000          /* Xbridge */
-#define BASE_XBOW_PORT  	8     /* Lowest external port */
-
-unsigned int bus_to_cpu[256];
-unsigned long bus_to_baddr[256];
-
-void __init pcibr_setup(cnodeid_t nid)
-{
-	int 			i, start, num;
-	unsigned long		masterwid;
-	bridge_t 		*bridge; 
-	volatile u64 		hubreg;
-	nasid_t	 		nasid, masternasid;
-	xwidget_part_num_t	partnum;
-	widgetreg_t 		widget_id;
-	static spinlock_t	pcibr_setup_lock = SPIN_LOCK_UNLOCKED;
-
-	/*
-	 * If the master is doing this for headless node, nothing to do.
-	 * This is because currently we require at least one of the hubs
-	 * (master hub) connected to the xbow to have at least one enabled 
-	 * cpu to receive intrs. Else we need an array bus_to_intrnasid[] 
-	 * that bridge_startup() needs to use to target intrs. All dma is
-	 * routed thru the widget of the master hub. The master hub wid
-	 * is selectable by WIDGET_A below.
-	 */
-	if (nid != get_compact_nodeid())
-		return;
-	/*
-	 * find what's on our local node
-	 */
-	spin_lock(&pcibr_setup_lock);
-	start = num_bridges;		/* Remember where we start from */
-	nasid = COMPACT_TO_NASID_NODEID(nid);
-	hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	if (hubreg & IIO_LLP_CSR_IS_UP) {
-		/* link is up */
-		widget_id = *(volatile widgetreg_t *)
-                        (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-		partnum = XWIDGET_PART_NUM(widget_id);
-		printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
-					smp_processor_id(), nasid, partnum);
-		if (partnum == BRIDGE_WIDGET_PART_NUM) {
-			/*
-			 * found direct connected bridge so must be Origin200
-			 */
-			printk("...is bridge\n");
-			num_bridges = 1;
-        		bus_to_wid[0] = 0x8;
-			bus_to_nid[0] = 0;
-			masterwid = 0xa;
-			bus_to_baddr[0] = 0xa100000000000000UL;
-		} else if (partnum == XBOW_WIDGET_PART_NUM) {
-			lboard_t *brd;
-			klxbow_t *xbow_p;
-			/*
-			 * found xbow, so may have multiple bridges
-			 * need to probe xbow
-			 */
-			printk("...is xbow\n");
-
-			if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
-                                   KLTYPE_MIDPLANE8)) == NULL)
-				printk("argh\n");
-			else
-				printk("brd = 0x%lx\n", (unsigned long) brd);
-			if ((xbow_p = (klxbow_t *)
-			     find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
-				printk("argh\n");
-			else {
-			   /*
-			    * Okay, here's a xbow. Lets arbitrate and find
-			    * out if we should initialize it. Set enabled 
-			    * hub connected at highest or lowest widget as 
-			    * master.
-			    */
-#ifdef WIDGET_A
-			   i = HUB_WIDGET_ID_MAX + 1;
-			   do {
-				i--;
-			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
-					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
-#else
-			   i = HUB_WIDGET_ID_MIN - 1;
-			   do {
-				i++;
-			   } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
-					(!XBOW_PORT_IS_ENABLED(xbow_p, i)));
-#endif
-			   masterwid = i;
-			   masternasid = XBOW_PORT_NASID(xbow_p, i);
-			   if (nasid == masternasid)
-			   for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
-				if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
-					continue;
-				if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
-				   widget_id = *(volatile widgetreg_t *)
-                        		   (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
-				   partnum = XWIDGET_PART_NUM(widget_id);
-				   if (partnum == BRIDGE_WIDGET_PART_NUM) {
-					printk("widget 0x%x is a bridge\n", i);
-					bus_to_wid[num_bridges] = i;
-					bus_to_nid[num_bridges] = nasid;
-					bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56));	/* Barrier set */
-					num_bridges++;
-				   }
-				}
-			   }
-			}
-		} else if (partnum == XXBOW_WIDGET_PART_NUM) {
-			/*
-			 * found xbridge, assume ibrick for now 
-			 */
-			printk("...is xbridge\n");
-        		bus_to_wid[0] = 0xb;
-        		bus_to_wid[1] = 0xe;
-        		bus_to_wid[2] = 0xf;
-
-        		bus_to_nid[0] = 0;
-        		bus_to_nid[1] = 0;
-        		bus_to_nid[2] = 0;
-
-			bus_to_baddr[0] = 0xa100000000000000UL;
-			bus_to_baddr[1] = 0xa100000000000000UL;
-			bus_to_baddr[2] = 0xa100000000000000UL;
-			masterwid = 0xa;
-			num_bridges = 3;
-		}
-	}
-	num = num_bridges - start;
-	spin_unlock(&pcibr_setup_lock);
-	/*
-         * set bridge registers
-         */
-	for (i = start; i < (start + num); i++) {
-
-		DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %d\n",
-                        i, i, bus_to_wid[i], i, bus_to_nid[i]);
-
-		bus_to_cpu[i] = smp_processor_id();
-		/*
-		 * point to this bridge
-		 */
-		bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
-		/*
-	 	 * Clear all pending interrupts.
-	 	 */
-		bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
-		/*
-	 	 * Until otherwise set up, assume all interrupts are from slot 0
-	 	 */
-		bridge->b_int_device = (u32) 0x0;
-		/*
-	 	 * swap pio's to pci mem and io space (big windows)
-	 	 */
-		bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
-		bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
-
-		/*
-		 * Hmm...  IRIX sets additional bits in the address which 
-		 * are documented as reserved in the bridge docs.
-		 */
-		bridge->b_int_mode = 0x0;		/* Don't clear ints */
-		bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
-		bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/
-		bridge->b_dir_map = (masterwid << 20);	/* DMA */
-		bridge->b_int_enable = 0;
-
-		bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
-	}
-}
-
-extern void ip27_setup_console(void);
-extern void ip27_time_init(void);
-
-void __init ip27_setup(void)
-{
-	nasid_t nid;
-	hubreg_t p, e;
-
-	ip27_setup_console();
-
-	num_bridges = 0;
-	/*
-	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
-	 */
-	DBG("ip27_setup(): Entered.\n");
-	nid = get_nasid();
-	printk("IP27: Running on node %d.\n", nid);
-
-	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
-	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
-	printk("Node %d has %s primary CPU%s.\n", nid,
-	       p ? "a" : "no",
-	       e ? ", CPU is running" : "");
-
-	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
-	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
-	printk("Node %d has %s secondary CPU%s.\n", nid,
-	       p ? "a" : "no",
-	       e ? ", CPU is running" : "");
-
-	verify_mode();
-	ioc3_sio_init();
-	ioc3_eth_init();
-	per_cpu_init();
-
-	mips_io_port_base = IO_BASE;
-	board_time_init = ip27_time_init;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-timer.c linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-timer.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip27/ip27-timer.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip27/ip27-timer.c	Wed Dec 31 16:00:00 1969
@@ -1,239 +0,0 @@
-/*
- * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
- * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/param.h>
-#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>
-#include <asm/m48t35.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hub.h>
-
-/*
- * 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.
- *
- * Ralf: which clock rate is used to feed the counter?
- */
-#define NSEC_PER_CYCLE		800
-#define NSEC_PER_SEC		1000000000
-#define CYCLES_PER_SEC		(NSEC_PER_SEC/NSEC_PER_CYCLE)
-#define CYCLES_PER_JIFFY	(CYCLES_PER_SEC/HZ)
-
-static unsigned long ct_cur[NR_CPUS];	/* What counter should be at next timer irq */
-static long last_rtc_update;		/* Last time the rtc clock got updated */
-
-extern rwlock_t xtime_lock;
-extern volatile unsigned long wall_jiffies;
-
-
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	struct m48t35_rtc *rtc;
-	nasid_t nid;
-
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + 
-							IOC3_BYTEBUS_DEV0);
-
-	rtc->control |= M48T35_RTC_READ;
-	cmos_minutes = rtc->min;
-	BCD_TO_BIN(cmos_minutes);
-	rtc->control &= ~M48T35_RTC_READ;
-
-	/*
-	 * 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) {
-		BIN_TO_BCD(real_seconds);
-		BIN_TO_BCD(real_minutes);
-		rtc->control |= M48T35_RTC_SET;
-		rtc->sec = real_seconds;
-		rtc->min = real_minutes;
-		rtc->control &= ~M48T35_RTC_SET;
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
-		retval = -1;
-	}
-
-	return retval;
-}
-
-void rt_timer_interrupt(struct pt_regs *regs)
-{
-	int cpu = smp_processor_id();
-	int cpuA = ((cputoslice(cpu)) == 0);
-	int irq = 9;				/* XXX Assign number */
-
-	irq_enter(cpu, irq);
-	write_lock(&xtime_lock);
-
-again:
-	LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
-	ct_cur[cpu] += CYCLES_PER_JIFFY;
-	LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
-
-	if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
-		goto again;
-
-	kstat.irqs[cpu][irq]++;		/* kstat only for bootcpu? */
-
-	if (cpu == 0)
-		do_timer(regs);
-
-#ifdef CONFIG_SMP
-	update_process_times(user_mode(regs));
-#endif /* CONFIG_SMP */
-	
-	/*
-	 * If we have an externally synchronized Linux clock, then update
-	 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-	 * called as close as possible to when a second starts.
-	 */
-	if ((time_status & STA_UNSYNC) == 0 &&
-	    xtime.tv_sec > last_rtc_update + 660) {
-		if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
-			if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
-				last_rtc_update = xtime.tv_sec;
-			else    
-				last_rtc_update = xtime.tv_sec - 600;
-		} else if (xtime.tv_usec <= ((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;
-		}
-        }
-
-	write_unlock(&xtime_lock);
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
-}
-
-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;
-}
-
-/* Includes for ioc3_init().  */
-#include <asm/sn/types.h>
-#include <asm/sn/sn0/addrs.h>
-#include <asm/sn/sn0/hubni.h>
-#include <asm/sn/sn0/hubio.h>
-#include <asm/pci/bridge.h>
-
-static __init unsigned long get_m48t35_time(void)
-{
-        unsigned int year, month, date, hour, min, sec;
-	struct m48t35_rtc *rtc;
-	nasid_t nid;
-
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + 
-							IOC3_BYTEBUS_DEV0);
-
-	rtc->control |= M48T35_RTC_READ;
-	sec = rtc->sec;
-	min = rtc->min;
-	hour = rtc->hour;
-	date = rtc->date;
-	month = rtc->month;
-	year = rtc->year;
-	rtc->control &= ~M48T35_RTC_READ;
-
-        BCD_TO_BIN(sec);
-        BCD_TO_BIN(min);
-        BCD_TO_BIN(hour);
-        BCD_TO_BIN(date);
-        BCD_TO_BIN(month);
-        BCD_TO_BIN(year);
-
-        year += 1970;
-
-        return mktime(year, month, date, hour, min, sec);
-}
-
-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)
-{
-	lboard_t *board;
-	klcpu_t *cpu;
-	int cpuid;
-
-	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
-	board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
-	if (!board)
-		panic("Can't find board info for myself.");
-
-	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
-	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
-	if (!cpu)
-		panic("No information about myself?");
-
-	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
-
-	set_cp0_status(SRB_TIMOCLK);
-}
-
-void __init hub_rtc_init(cnodeid_t cnode)
-{
-	/*
-	 * We only need to initialize the current node.
-	 * If this is not the current node then it is a cpuless
-	 * node and timeouts will not happen there.
-	 */
-	if (get_compact_nodeid() == cnode) {
-		int cpu = smp_processor_id();
-		LOCAL_HUB_S(PI_RT_EN_A, 1);
-		LOCAL_HUB_S(PI_RT_EN_B, 1);
-		LOCAL_HUB_S(PI_PROF_EN_A, 0);
-		LOCAL_HUB_S(PI_PROF_EN_B, 0);
-		ct_cur[cpu] = CYCLES_PER_JIFFY;
-		LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
-		LOCAL_HUB_S(PI_RT_COUNT, 0);
-		LOCAL_HUB_S(PI_RT_PEND_A, 0);
-		LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
-		LOCAL_HUB_S(PI_RT_COUNT, 0);
-		LOCAL_HUB_S(PI_RT_PEND_B, 0);
-	}
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/Makefile linux-2.4.20-pre7/arch/mips64/sgi-ip32/Makefile
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,22 +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...
-
-USE_STANDARD_AS_RULE := true
-
-O_TARGET := ip32-kern.a
-
-all: ip32-kern.a ip32-irq-glue.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
-
-obj-$(CONFIG_PCI)   += ip32-pci.o
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/crime.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/crime.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/crime.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/crime.c	Wed Dec 31 16:00:00 1969
@@ -1,49 +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) 2001 Keith M Wesolowski
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/ip32/crime.h>
-#include <asm/ptrace.h>
-
-void __init crime_init (void)
-{
-	u64 id = crime_read_64 (CRIME_ID);
-	u64 rev = id & CRIME_ID_REV;
-
-	id = (id & CRIME_ID_IDBITS) >> 4;
-
-	printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev,
-		(unsigned long) CRIME_BASE);
-}
-
-/* XXX Like on Sun, these give us various useful information to printk. */
-void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
-{
-	u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT);
-	u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR);
-	memerr &= CRIME_MEM_ERROR_STAT_MASK;
-	
-	printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n",
-		addr << 2, memerr);
-
-	crime_write_64 (CRIME_MEM_ERROR_STAT, 0);
-}
-
-void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
-{
-	u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT);
-	u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR);
-	cpuerr &= CRIME_CPU_ERROR_MASK;
-	addr <<= 2UL;
-
-	printk ("CRIME CPU interface error detected at %09lx status %08lx\n",
-		addr, cpuerr);
-
-	crime_write_64 (CRIME_CPU_ERROR_STAT, 0);
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-berr.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-berr.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-berr.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-berr.c	Wed Dec 31 16:00:00 1969
@@ -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.
- *
- * 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/addrspace.h>
-#include <asm/ptrace.h>
-
-int
-be_ip32_handler(struct pt_regs *regs, int is_fixup)
-{
-	int data = regs->cp0_cause & 4;
-
-	if (is_fixup)
-		return MIPS_BE_FIXUP;
-
-	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_all();
-	while(1);
-	force_sig(SIGBUS, current);
-}
-
-void __init
-bus_error_init(void)
-{
-	be_board_handler = be_ip27_handler;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-irq-glue.S linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-irq-glue.S
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-irq-glue.S	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-irq-glue.S	Wed Dec 31 16:00:00 1969
@@ -1,87 +0,0 @@
-/*
- * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
- *
- * This file is subject to 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
- * Copyright (C) 2001 Keith M Wesolowski
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/stackframe.h>
-#include <asm/addrspace.h>
-#include <asm/ip32/ip32_ints.h>
-
-		.text
-		.set    noreorder
-		.set    noat
-		.align  5
-		NESTED(ip32_handle_int, PT_SIZE, ra)
-		.set    noat
-		SAVE_ALL
-		CLI			# TEST: interrupts should be off
-		.set    at
-		.set    noreorder
-
-		mfc0	s0,CP0_CAUSE
-
-		andi	t1, s0, IE_IRQ0
-		bnez	t1, handle_irq0
-		 andi	t1, s0, IE_IRQ1
-		bnez	t1, handle_irq1
-		 andi	t1, s0, IE_IRQ2
-		bnez	t1, handle_irq2
-		 andi	t1, s0, IE_IRQ3
-		bnez	t1, handle_irq3
-		 andi	t1, s0, IE_IRQ4
-		bnez	t1, handle_irq4
-		 andi	t1, s0, IE_IRQ5
-		bnez	t1, handle_irq5
-		 nop
-
-		/* Either someone has triggered the "software interrupts"
-		 * or we lost an interrupt somehow.  Ignore it.
-		 */
-		j	ret_from_irq
-		 nop
-
-handle_irq0:
-		jal	ip32_irq0
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq1:
-		jal	ip32_irq1
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq2:
-		jal	ip32_irq2
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq3:
-		jal	ip32_irq3
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq4:
-		jal	ip32_irq4
-		 move	a0, sp
-		j	ret_from_irq
-		 nop
-
-handle_irq5:
-		jal	ip32_irq5
-		move	a0, sp
-		j	ret_from_irq
-		 nop
-
-		END(ip32_handle_int)
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-irq.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-irq.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-irq.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-irq.c	Wed Dec 31 16:00:00 1969
@@ -1,571 +0,0 @@
-/*
- * Code to handle IP32 IRQs
- *
- * This file is subject to 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
- * Copyright (C) 2001 Keith M Wesolowski
- */
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/types.h>
-#include <linux/interrupt.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>
-#include <asm/system.h>
-#include <asm/ip32/ip32_ints.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/mace.h>
-#include <asm/signal.h>
-
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* O2 irq map
- *
- * IP0 -> software (ignored)
- * IP1 -> software (ignored)
- * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
- * IP3 -> (irq1) X unknown
- * IP4 -> (irq2) X unknown
- * IP5 -> (irq3) X unknown
- * IP6 -> (irq4) X unknown
- * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
- *
- * crime: (C)
- *
- * CRIME_INT_STAT 31:0:
- *
- * 0 -> 1 Video in 1
- * 1 -> 2 Video in 2
- * 2 -> 3 Video out
- * 3 -> 4 Mace ethernet
- * 4 -> S  SuperIO sub-interrupt
- * 5 -> M  Miscellaneous sub-interrupt
- * 6 -> A  Audio sub-interrupt
- * 7 -> 8  PCI bridge errors
- * 8 -> 9  PCI SCSI aic7xxx 0
- * 9 -> 10  PCI SCSI aic7xxx 1
- * 10 -> 11 PCI slot 0
- * 11 -> 12 unused (PCI slot 1)
- * 12 -> 13 unused (PCI slot 2)
- * 13 -> 14 unused (PCI shared 0)
- * 14 -> 15 unused (PCI shared 1)
- * 15 -> 16 unused (PCI shared 2)
- * 16 -> 17 GBE0 (E)
- * 17 -> 18 GBE1 (E)
- * 18 -> 19 GBE2 (E)
- * 19 -> 20 GBE3 (E)
- * 20 -> 21 CPU errors
- * 21 -> 22 Memory errors
- * 22 -> 23 RE empty edge (E)
- * 23 -> 24 RE full edge (E)
- * 24 -> 25 RE idle edge (E)
- * 25 -> 26 RE empty level
- * 26 -> 27 RE full level
- * 27 -> 28 RE idle level
- * 28 -> 29  unused (software 0) (E)
- * 29 -> 30  unused (software 1) (E)
- * 30 -> 31  unused (software 2) - crime 1.5 CPU SysCorError (E)
- * 31 -> 32 VICE
- *
- * S, M, A: Use the MACE ISA interrupt register
- * MACE_ISA_INT_STAT 31:0
- *
- * 0-7 -> 33-40 Audio
- * 8 -> 41 RTC
- * 9 -> 42 Keyboard
- * 10 -> X Keyboard polled
- * 11 -> 44 Mouse
- * 12 -> X Mouse polled
- * 13-15 -> 46-48 Count/compare timers
- * 16-19 -> 49-52 Parallel (16 E)
- * 20-25 -> 53-58 Serial 1 (22 E)
- * 26-31 -> 59-64 Serial 2 (28 E)
- *
- * Note that this means IRQs 5-7, 43, and 45 do not exist.  This is a
- * different IRQ map than IRIX uses, but that's OK as Linux irq handling
- * is quite different anyway.
- */
-
-/* Some initial interrupts to set up */
-extern void crime_memerr_intr (unsigned int irq, void *dev_id,
-			       struct pt_regs *regs);
-extern void crime_cpuerr_intr (unsigned int irq, void *dev_id,
-			       struct pt_regs *regs);
-
-struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
-			       0, "CRIME memory error", NULL,
-			       NULL };
-struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
-			       0, "CRIME CPU error", NULL,
-			       NULL };
-
-extern void ip32_handle_int (void);
-asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
-
-/*
- * 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)
-{
-	set_cp0_status(STATUSF_IP7);
-}
-
-static unsigned int startup_cpu_irq(unsigned int irq)
-{
-	enable_cpu_irq(irq);
-	return 0;
-}
-
-static void disable_cpu_irq(unsigned int irq)
-{
-	clear_cp0_status(STATUSF_IP7);
-}
-
-static void end_cpu_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_cpu_irq (irq);
-}
-
-#define shutdown_cpu_irq disable_cpu_irq
-#define mask_and_ack_cpu_irq disable_cpu_irq
-
-static struct hw_interrupt_type ip32_cpu_interrupt = {
-	"IP32 CPU",
-	startup_cpu_irq,
-	shutdown_cpu_irq,
-	enable_cpu_irq,
-	disable_cpu_irq,
-	mask_and_ack_cpu_irq,
-	end_cpu_irq,
-	NULL
-};
-
-/*
- * This is for pure CRIME interrupts - ie not MACE.  The advantage?
- * We get to split the register in half and do faster lookups.
- */
-
-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);
-	crime_mask |= 1 << (irq - 1);
-	crime_write_64(CRIME_INT_MASK, crime_mask);
-	restore_flags(flags);
-}
-
-static unsigned int startup_crime_irq(unsigned int 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)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	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);
-}
-
-static void mask_and_ack_crime_irq (unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	/* Edge triggered interrupts must be cleared. */
-	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);
-		crime_mask &= ~(1 << (irq - 1));
-		crime_write_64(CRIME_HARD_INT, crime_mask);
-		restore_flags(flags);
-	}
-	disable_crime_irq(irq);
-}
-
-static void end_crime_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_crime_irq (irq);
-}
-
-#define shutdown_crime_irq disable_crime_irq
-
-static struct hw_interrupt_type ip32_crime_interrupt = {
-	"IP32 CRIME",
-	startup_crime_irq,
-	shutdown_crime_irq,
-	enable_crime_irq,
-	disable_crime_irq,
-	mask_and_ack_crime_irq,
-	end_crime_irq,
-	NULL
-};
-
-/*
- * 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)
-{
-	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;
-	 * however, we never disable interrupts at that level.
-	 */
-	crime_mask = crime_read_64(CRIME_INT_MASK);
-	crime_mask |= 1 << (irq - 1);
-	crime_write_64(CRIME_INT_MASK, crime_mask);
-	restore_flags(flags);
-}
-
-static unsigned int startup_macepci_irq(unsigned int irq)
-{
-	enable_macepci_irq (irq);
-
-	return 0; /* XXX */
-}
-
-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);
-}
-
-static void end_macepci_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_macepci_irq (irq);
-}
-
-#define shutdown_macepci_irq disable_macepci_irq
-#define mask_and_ack_macepci_irq disable_macepci_irq
-
-static struct hw_interrupt_type ip32_macepci_interrupt = {
-	"IP32 MACE PCI",
-	startup_macepci_irq,
-	shutdown_macepci_irq,
-	enable_macepci_irq,
-	disable_macepci_irq,
-	mask_and_ack_macepci_irq,
-	end_macepci_irq,
-	NULL
-};
-
-/* This is used for MACE ISA interrupts.  That means bits 4-6 in the
- * CRIME register.
- */
-
-static void enable_maceisa_irq (unsigned int irq)
-{
-	u64 crime_mask;
-	u32 mace_mask;
-	unsigned int crime_int = 0;
-	unsigned long flags;
-
-	DBG ("maceisa enable: %u\n", irq);
-	
-	switch (irq) {
-	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
-		crime_int = MACE_AUDIO_INT;
-		break;
-	case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
-		crime_int = MACE_MISC_INT;
-		break;
-	case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
-		crime_int = MACE_SUPERIO_INT;
-		break;
-	}
-	DBG ("crime_int %016lx enabled\n", crime_int);
-	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);
-	mace_mask |= 1 << (irq - 33);
-	mace_write_32(MACEISA_INT_MASK, mace_mask);
-	restore_flags(flags);
-}
-
-static unsigned int startup_maceisa_irq (unsigned int irq)
-{
-	enable_maceisa_irq(irq);
-	return 0;
-}
-
-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 &= ~(1 << (irq - 33));
-	mace_write_32(MACEISA_INT_MASK, mace_mask);
-	restore_flags(flags);
-}
-
-static void mask_and_ack_maceisa_irq(unsigned int irq)
-{
-	u32 mace_mask;
-	unsigned long flags;
-
-	switch (irq) {
-	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);
-		mace_mask &= ~(1 << (irq - 33));
-		mace_write_32(MACEISA_INT_STAT, mace_mask);
-		restore_flags(flags);
-		break;
-	}
-	disable_maceisa_irq(irq);
-}
-
-static void end_maceisa_irq(unsigned irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_maceisa_irq (irq);
-}
-
-#define shutdown_maceisa_irq disable_maceisa_irq
-
-static struct hw_interrupt_type ip32_maceisa_interrupt = {
-	"IP32 MACE ISA",
-	startup_maceisa_irq,
-	shutdown_maceisa_irq,
-	enable_maceisa_irq,
-	disable_maceisa_irq,
-	mask_and_ack_maceisa_irq,
-	end_maceisa_irq,
-	NULL
-};
-
-/* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
- * bits 0-3 and 7 in the CRIME register.
- */
-
-static void enable_mace_irq(unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	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);
-}
-
-static unsigned int startup_mace_irq(unsigned int irq)
-{
-	enable_mace_irq(irq);
-	return 0;
-}
-
-static void disable_mace_irq(unsigned int irq)
-{
-	u64 crime_mask;
-	unsigned long flags;
-
-	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);
-}
-
-static void end_mace_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		enable_mace_irq (irq);
-}
-
-#define shutdown_mace_irq disable_mace_irq
-#define mask_and_ack_mace_irq disable_mace_irq
-
-static struct hw_interrupt_type ip32_mace_interrupt = {
-	"IP32 MACE",
-	startup_mace_irq,
-	shutdown_mace_irq,
-	enable_mace_irq,
-	disable_mace_irq,
-	mask_and_ack_mace_irq,
-	end_mace_irq,
-	NULL
-};
-
-static void ip32_unknown_interrupt (struct pt_regs *regs)
-{
-	u64 crime;
-	u32 mace;
-	
-	printk ("Unknown interrupt occurred!\n");
-	printk ("cp0_status: %08x\tcp0_cause: %08x\n",
-		read_32bit_cp0_register (CP0_STATUS),
-		read_32bit_cp0_register (CP0_CAUSE));
-	crime = crime_read_64 (CRIME_INT_MASK);
-	printk ("CRIME interrupt mask: %016lx\n", crime);
-	crime = crime_read_64 (CRIME_INT_STAT);
-	printk ("CRIME interrupt status: %016lx\n", crime);
-	crime = crime_read_64 (CRIME_HARD_INT);
-	printk ("CRIME hardware interrupt register: %016lx\n", crime);
-	mace = mace_read_32 (MACEISA_INT_MASK);
-	printk ("MACE ISA interrupt mask: %08x\n", mace);
-	mace = mace_read_32 (MACEISA_INT_STAT);
-	printk ("MACE ISA interrupt status: %08x\n", mace);
-	mace = mace_read_32 (MACEPCI_CONTROL);
-	printk ("MACE PCI control register: %08x\n", mace);
-
-	printk("Register dump:\n");
-	show_regs(regs);
-
-	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)
-{
-	u64 crime_int = crime_read_64 (CRIME_INT_STAT);
-	int irq = 0;
-	
-	if (crime_int & CRIME_MACE_INT_MASK) {
-		crime_int &= CRIME_MACE_INT_MASK;
-		irq = ffs (crime_int);
-	} else if (crime_int & CRIME_MACEISA_INT_MASK) {
-		u32 mace_int;
-		mace_int = mace_read_32 (MACEISA_INT_STAT);
-		if (mace_int == 0)
-			irq = 0;
-		else
-			irq = ffs (mace_int) + 32;
-	} else if (crime_int & CRIME_MACEPCI_INT_MASK) {
-		crime_int &= CRIME_MACEPCI_INT_MASK;
-		crime_int >>= 8;
-		irq = ffs (crime_int) + 8;
-	} else if (crime_int & 0xffff0000) {
-		crime_int >>= 16;
-		irq = ffs (crime_int) + 16;
-	}
-	if (irq == 0)
-		ip32_unknown_interrupt(regs);
-	DBG("*irq %u*\n", irq);
-	do_IRQ(irq, regs);
-}
-
-void ip32_irq1(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq2(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq3(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (regs);
-}
-
-void ip32_irq4(struct pt_regs *regs)
-{
-	ip32_unknown_interrupt (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 -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-pci.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-pci.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-pci.c	Wed Dec 31 16:00:00 1969
@@ -1,460 +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, 2001 Keith M Wesolowski
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <asm/pci.h>
-#include <asm/ip32/mace.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/ip32_ints.h>
-#include <linux/delay.h>
-
-#undef DEBUG_MACE_PCI
-
-/*
- * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
- * map looks like this:
- *
- * 0  aic7xxx 0
- * 1  aic7xxx 1
- * 2  expansion slot
- * 3  N/C
- * 4  N/C
- */
-
-#define chkslot(dev)							\
-do {									\
-	if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1	\
-	    || PCI_SLOT ((dev)->devfn) > 3)				\
-		return PCIBIOS_DEVICE_NOT_FOUND;			\
-} while (0)
-		
-#define mkaddr(dev, where) \
-((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
-
-void macepci_error (int irq, void *dev, struct pt_regs *regs);
-
-static int macepci_read_config_byte (struct pci_dev *dev, int where,
-				     u8 *val)
-{
-	*val = 0xff;
-	chkslot (dev);
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	*val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_read_config_word (struct pci_dev *dev, int where,
-				     u16 *val)
-{
-	*val = 0xffff;
-	chkslot (dev);
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
- 	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	*val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_read_config_dword (struct pci_dev *dev, int where,
-				      u32 *val)
-{
-	*val = 0xffffffff;
-	chkslot (dev);
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	*val = mace_read_32 (MACEPCI_CONFIG_DATA);
-	
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_byte (struct pci_dev *dev, int where,
-				      u8 val)
-{
-	chkslot (dev);
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_word (struct pci_dev *dev, int where,
-				      u16 val)
-{
-	chkslot (dev);
-	if (where & 1)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_dword (struct pci_dev *dev, int where,
-                                          u32 val)
-{
-	chkslot (dev);
-	if (where & 3)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
-	mace_write_32 (MACEPCI_CONFIG_DATA, val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macepci_ops = {
-	macepci_read_config_byte,
-	macepci_read_config_word,
-	macepci_read_config_dword,
-	macepci_write_config_byte,
-	macepci_write_config_word,
-	macepci_write_config_dword
-};
-
-struct pci_fixup pcibios_fixups[] = { { 0 } };
-
-void __init pcibios_init (void)
-{
-	struct pci_dev *dev;
-	u32 start, size;
-	u16 cmd;
-	u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
-	u32 base_mem = 0x80100000; /* Likewise */
-	u32 rev = mace_read_32 (MACEPCI_REV);
-	int i;
-
-	printk ("MACE: PCI rev %d detected at %016lx\n", rev,
-		(u64) MACE_BASE + MACE_PCI);
-
-	/* These are *bus* addresses */
-	ioport_resource.start = 0;
-	ioport_resource.end = 0xffffffffUL;
-	iomem_resource.start = 0x80000000UL;
-	iomem_resource.end = 0xffffffffUL;
-
-	/* Clear any outstanding errors and enable interrupts */
-	mace_write_32 (MACEPCI_ERROR_ADDR, 0);
-	mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
-	mace_write_32 (MACEPCI_CONTROL, 0xff008500);
-	crime_write_64 (CRIME_HARD_INT, 0UL);
-	crime_write_64 (CRIME_SOFT_INT, 0UL);
-	crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
-
-	if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
-			 "MACE PCI error", NULL))
-		panic("PCI bridge can't get interrupt; can't happen.");
-
-	pci_scan_bus (0, &macepci_ops, NULL);
-
-#ifdef DEBUG_MACE_PCI
-	pci_for_each_dev (dev) {
-		printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
-			dev->bus->number, PCI_SLOT (dev->devfn),
-			PCI_FUNC (dev->devfn));
-		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
-			if (dev->resource[i].start == 0)
-				continue;
-			printk ("%d: %016lx - %016lx (flags %04lx)\n",
-				i, dev->resource[i].start,
-				dev->resource[i].end, dev->resource[i].flags);
-		}
-	}
-#endif
-	/*
-	 * Assign sane resources to and enable all devices.  The requirement
-	 * for the SCSI controllers is well-known: a 256-byte I/O region
-	 * which we must assign, and a 1-page memory region which is
-	 * assigned by the system firmware.
-	 */
-	pci_for_each_dev (dev) {
-		switch (PCI_SLOT (dev->devfn)) {
-		case 1: /* SCSI bus 0 */
-			dev->resource[0].start = 0x1000UL;
-			dev->resource[0].end = 0x10ffUL;
-			break;
-		case 2: /* SCSI bus 1 */
-			dev->resource[0].start = 0x2000UL;
-			dev->resource[0].end = 0x20ffUL;
-			break;
-		default: /* Slots - I guess we have only 1 */
-			for (i=0; i < 6; i++) {
-				size = dev->resource[i].end
-					- dev->resource[i].start;
-				if (!size
-				    || !(dev->resource[i].flags
-					 & (IORESOURCE_IO|IORESOURCE_MEM))) {
-					dev->resource[i].start
-						= dev->resource[i].end = 0UL;
-					continue;
-				}
-				if (dev->resource[i].flags & IORESOURCE_IO) {
-					dev->resource[i].start = base_io;
-					base_io += PAGE_ALIGN (size);
-				} else {
-					dev->resource[i].start = base_mem;
-					base_mem += 0x100000UL;
-				}
-				dev->resource[i].end =
-					dev->resource[i].start + size;
-			}
-			break;
-		}
-		for (i=0; i < 6; i++) {
-			if (dev->resource[i].start == 0)
-				continue;
-			start = dev->resource[i].start;
-			if (dev->resource[i].flags & IORESOURCE_IO)
-				start |= 1;
-			pci_write_config_dword (dev, 
-				PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
-		}
-		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_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);
-
-	pci_for_each_dev (dev) {
-		printk ("Device: %d/%d/%d final bus resource map\n",
-			dev->bus->number, PCI_SLOT (dev->devfn),
-			PCI_FUNC (dev->devfn));
-		for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
-			if (dev->resource[i].start == 0)
-				continue;
-			printk ("%d: %016lx - %016lx (flags %04lx)\n",
-				i, dev->resource[i].start,
-				dev->resource[i].end, dev->resource[i].flags);
-		}
-	}
-#endif
-}
-
-/*
- * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
- * the device (1-4 => A-D), tell what irq to use.  Note that we don't
- * in theory have slots 4 and 5, and we never normally use the shared
- * irqs.  I suppose a device without a pin A will thank us for doing it
- * right if there exists such a broken piece of crap.
- */
-static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
-{
-	chkslot (dev);
-	if (pin == 0)
-		pin = 1;
-	switch (slot) {
-	case 1:
-		return MACEPCI_SCSI0_IRQ;
-	case 2:
-		return MACEPCI_SCSI1_IRQ;
-	case 3:
-		switch (pin) {
-		case 2:
-			return MACEPCI_SHARED0_IRQ;
-		case 3:
-			return MACEPCI_SHARED1_IRQ;
-		case 4:
-			return MACEPCI_SHARED2_IRQ;
-		case 1:
-		default:
-			return MACEPCI_SLOT0_IRQ;
-		}
-	case 4:
-		switch (pin) {
-		case 2:
-			return MACEPCI_SHARED2_IRQ;
-		case 3:
-			return MACEPCI_SHARED0_IRQ;
-		case 4:
-			return MACEPCI_SHARED1_IRQ;
-		case 1:
-		default:
-			return MACEPCI_SLOT1_IRQ;
-		}
-		return MACEPCI_SLOT1_IRQ;
-	case 5:
-		switch (pin) {
-		case 2:
-			return MACEPCI_SHARED1_IRQ;
-		case 3:
-			return MACEPCI_SHARED2_IRQ;
-		case 4:
-			return MACEPCI_SHARED0_IRQ;
-		case 1:
-		default:
-			return MACEPCI_SLOT2_IRQ;
-		}
-	default:
-		return 0;
-	}
-}
-
-/*
- * It's not entirely clear what this does in a system with no bridges.
- * In any case, bridges are not supported by Linux in O2.
- */
-static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
-{
-	if (PCI_SLOT (dev->devfn) == 2)
-		*pinp = 2;
-	else
-		*pinp = 1;
-	return PCI_SLOT (dev->devfn);
-}
-
-/* All devices are enabled during initialization. */
-int pcibios_enable_device (struct pci_dev *dev)
-{
-	return PCIBIOS_SUCCESSFUL;
-}
-
-char * __init pcibios_setup (char *str)
-{
-	return str;
-}
-
-void __init pcibios_align_resource (void *data, struct resource *res,
-				    unsigned long size)
-{
-}
-
-void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root,
-				     struct resource *res, int resource)
-{
-}
-
-void __init pcibios_update_irq (struct pci_dev *dev, int irq)
-{
-	pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
-}
-
-void __init pcibios_fixup_bus (struct pci_bus *b)
-{
-	pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
-}
-
-/* XXX anybody know what this is supposed to do? */
-void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
-				      struct pbus_set_ranges_data * ranges)
-{
-	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;
-}
-
-/*
- * Handle errors from the bridge.  This includes master and target aborts,
- * various command and address errors, and the interrupt test.  This gets
- * registered on the bridge error irq.  It's conceivable that some of these
- * conditions warrant a panic.  Anybody care to say which ones?
- */
-void macepci_error (int irq, void *dev, struct pt_regs *regs) {
-	u32 flags, error_addr;
-	char space;
-
-	flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
-	error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
-
-	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
-		space = 'M';
-	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
-		space = 'C';
-	else space = 'X';
-	
-	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
-		printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_MASTER_ABORT);
-	}
-	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
-		printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_TARGET_ABORT);
-	}
-	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
-		printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_DATA_PARITY_ERR);
-	}
-	if (flags & MACEPCI_ERROR_RETRY_ERR) {
-		printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_RETRY_ERR);
-	}
-	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
-		printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS,
-			       flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
-	}
-	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
-		printk ("MACEPCI: System error at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_SYSTEM_ERR);
-	}
-	if (flags & MACEPCI_ERROR_PARITY_ERR) {
-		printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
-			space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_PARITY_ERR);
-	}
-	if (flags & MACEPCI_ERROR_OVERRUN) {
-		printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
-			error_addr, space);
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_OVERRUN);
-	}
-	if (flags & MACEPCI_ERROR_SIG_TABORT) {
-		printk ("MACEPCI: Signaled target abort (clearing)\n");
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_SIG_TABORT);
-	}
-	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
-		printk ("MACEPCI: Interrupt test triggered (clearing)\n");
-		mace_write_32 (MACEPCI_ERROR_FLAGS, flags
-			       & ~MACEPCI_ERROR_INTERRUPT_TEST);
-	}
-}
-unsigned __init int pcibios_assign_all_busses(void)
-{
-	return 0;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-reset.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-reset.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-reset.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-reset.c	Wed Dec 31 16:00:00 1969
@@ -1,34 +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) 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 -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-rtc.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-rtc.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-rtc.c	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-rtc.c	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- * RTC routines for IP32 style attached 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) 2000 Harald Koerfgen
- */
-#include <linux/mc146818rtc.h>
-#include <asm/ip32/mace.h>
-
-static unsigned char ip32_rtc_read_data(unsigned long addr)
-{
-	return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8));
-}
-
-static void ip32_rtc_write_data(unsigned char data, unsigned long addr)
-{
-	mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data);
-}
-
-static int ip32_rtc_bcd_mode(void)
-{
-	return 0;
-}
-
-struct rtc_ops ip32_rtc_ops = {
-	&ip32_rtc_read_data,
-	&ip32_rtc_write_data,
-	&ip32_rtc_bcd_mode
-};
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-setup.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-setup.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-setup.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-setup.c	Wed Dec 31 16:00:00 1969
@@ -1,102 +0,0 @@
-/*
- * IP32 basic setup
- *
- * This file is subject to 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
- */
-#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 <asm/time.h>
-#include <asm/mipsregs.h>
-#include <asm/bootinfo.h>
-#include <asm/mmu_context.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/mace.h>
-#include <asm/ip32/ip32_ints.h>
-#include <asm/sgialib.h>
-
-extern struct rtc_ops ip32_rtc_ops;
-extern u32 cc_interval;
-
-#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
-	char *ctype;
-#endif
-	TLBMISS_HANDLER_SETUP ();
-
-	mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	ctype = ArcGetEnvironmentVariable("console");
-	if (*ctype == 'd') {
-		if (ctype[1] == '2')
-			console_setup ("ttyS1");
-		else
-			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 ();
-}
-
-int __init page_is_ram (unsigned long pagenr)
-{
-	/* XXX: to do? */
-	return 1;
-}
diff -urN linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-timer.c linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-timer.c
--- linux-2.4.20-pre6/arch/mips64/sgi-ip32/ip32-timer.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/sgi-ip32/ip32-timer.c	Wed Dec 31 16:00:00 1969
@@ -1,238 +0,0 @@
-/*
- * IP32 timer calibration
- *
- * This file is subject to 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
- */
-#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;
-
-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)
-{
-	u64 crime_time;
-	u32 cc_tick;
-
-	printk("Calibrating system timer... ");
-
-	crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
-	cc_tick = read_32bit_cp0_register (CP0_COUNT);
-
-	while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time 
-		< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
-		;
-	cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick;
-	cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
-	/* The round-off seems unnecessary; in testing, the error of the
-	 * above procedure is < 100 ticks, which means it gets filtered
-	 * out by the HZ adjustment. 
-	 */
-	cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
-
-	printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
-
-	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 -urN linux-2.4.20-pre6/arch/mips64/tools/Makefile linux-2.4.20-pre7/arch/mips64/tools/Makefile
--- linux-2.4.20-pre6/arch/mips64/tools/Makefile	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/arch/mips64/tools/Makefile	Wed Dec 31 16:00:00 1969
@@ -1,26 +0,0 @@
-#
-# Makefile for MIPS kernel build tools.
-#
-# Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
-# Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org)
-# Copyright (C) 1999 Silicon Graphics, Inc.
-#
-TARGET	:= $(TOPDIR)/include/asm-$(ARCH)/offset.h
-
-USE_STANDARD_AS_RULE := true
-
-$(TARGET): offset.h
-	cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
-
-offset.h: offset.s
-	sed -n '/^@@@/s///p' $^ >$@
-
-offset.s: offset.c $(TOPDIR)/include/linux/autoconf.h
-
-clean:
-	rm -f offset.[hs] $(TARGET).new
-	
-mrproper: clean
-	rm -f $(TARGET)
-
-include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/arch/mips64/tools/offset.c linux-2.4.20-pre7/arch/mips64/tools/offset.c
--- linux-2.4.20-pre6/arch/mips64/tools/offset.c	Thu Jul 27 18:36:54 2000
+++ linux-2.4.20-pre7/arch/mips64/tools/offset.c	Wed Dec 31 16:00:00 1969
@@ -1,150 +0,0 @@
-/*
- * offset.c: Calculate pt_regs and task_struct offsets.
- *
- * Copyright (C) 1996 David S. Miller
- * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-
-#define text(t) __asm__("\n@@@" t)
-#define _offset(type, member) (&(((type *)NULL)->member))
-
-#define offset(string, ptr, member) \
-	__asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
-#define size(string, size) \
-	__asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
-#define linefeed text("")
-
-text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */");
-linefeed;
-text("#ifndef _MIPS_OFFSET_H");
-text("#define _MIPS_OFFSET_H");
-linefeed;
-
-void output_ptreg_defines(void)
-{
-	text("/* MIPS pt_regs offsets. */");
-	offset("#define PT_R0     ", struct pt_regs, regs[0]);
-	offset("#define PT_R1     ", struct pt_regs, regs[1]);
-	offset("#define PT_R2     ", struct pt_regs, regs[2]);
-	offset("#define PT_R3     ", struct pt_regs, regs[3]);
-	offset("#define PT_R4     ", struct pt_regs, regs[4]);
-	offset("#define PT_R5     ", struct pt_regs, regs[5]);
-	offset("#define PT_R6     ", struct pt_regs, regs[6]);
-	offset("#define PT_R7     ", struct pt_regs, regs[7]);
-	offset("#define PT_R8     ", struct pt_regs, regs[8]);
-	offset("#define PT_R9     ", struct pt_regs, regs[9]);
-	offset("#define PT_R10    ", struct pt_regs, regs[10]);
-	offset("#define PT_R11    ", struct pt_regs, regs[11]);
-	offset("#define PT_R12    ", struct pt_regs, regs[12]);
-	offset("#define PT_R13    ", struct pt_regs, regs[13]);
-	offset("#define PT_R14    ", struct pt_regs, regs[14]);
-	offset("#define PT_R15    ", struct pt_regs, regs[15]);
-	offset("#define PT_R16    ", struct pt_regs, regs[16]);
-	offset("#define PT_R17    ", struct pt_regs, regs[17]);
-	offset("#define PT_R18    ", struct pt_regs, regs[18]);
-	offset("#define PT_R19    ", struct pt_regs, regs[19]);
-	offset("#define PT_R20    ", struct pt_regs, regs[20]);
-	offset("#define PT_R21    ", struct pt_regs, regs[21]);
-	offset("#define PT_R22    ", struct pt_regs, regs[22]);
-	offset("#define PT_R23    ", struct pt_regs, regs[23]);
-	offset("#define PT_R24    ", struct pt_regs, regs[24]);
-	offset("#define PT_R25    ", struct pt_regs, regs[25]);
-	offset("#define PT_R26    ", struct pt_regs, regs[26]);
-	offset("#define PT_R27    ", struct pt_regs, regs[27]);
-	offset("#define PT_R28    ", struct pt_regs, regs[28]);
-	offset("#define PT_R29    ", struct pt_regs, regs[29]);
-	offset("#define PT_R30    ", struct pt_regs, regs[30]);
-	offset("#define PT_R31    ", struct pt_regs, regs[31]);
-	offset("#define PT_LO     ", struct pt_regs, lo);
-	offset("#define PT_HI     ", struct pt_regs, hi);
-	offset("#define PT_EPC    ", struct pt_regs, cp0_epc);
-	offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
-	offset("#define PT_STATUS ", struct pt_regs, cp0_status);
-	offset("#define PT_CAUSE  ", struct pt_regs, cp0_cause);
-	size("#define PT_SIZE   ", struct pt_regs);
-	linefeed;
-}
-
-void output_task_defines(void)
-{
-	text("/* MIPS task_struct offsets. */");
-	offset("#define TASK_STATE         ", struct task_struct, state);
-	offset("#define TASK_FLAGS         ", struct task_struct, flags);
-	offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
-	offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
-	offset("#define TASK_PTRACE        ", struct task_struct, ptrace);
-	offset("#define TASK_COUNTER       ", struct task_struct, counter);
-	offset("#define TASK_NICE          ", struct task_struct, nice);
-	offset("#define TASK_MM            ", struct task_struct, mm);
-	offset("#define TASK_PROCESSOR     ", struct task_struct, processor);
-	size("#define TASK_STRUCT_SIZE   ", struct task_struct);
-	linefeed;
-}
-
-void output_thread_defines(void)
-{
-	text("/* MIPS specific thread_struct offsets. */");
-	offset("#define THREAD_REG16   ", struct task_struct, thread.reg16);
-	offset("#define THREAD_REG17   ", struct task_struct, thread.reg17);
-	offset("#define THREAD_REG18   ", struct task_struct, thread.reg18);
-	offset("#define THREAD_REG19   ", struct task_struct, thread.reg19);
-	offset("#define THREAD_REG20   ", struct task_struct, thread.reg20);
-	offset("#define THREAD_REG21   ", struct task_struct, thread.reg21);
-	offset("#define THREAD_REG22   ", struct task_struct, thread.reg22);
-	offset("#define THREAD_REG23   ", struct task_struct, thread.reg23);
-	offset("#define THREAD_REG29   ", struct task_struct, thread.reg29);
-	offset("#define THREAD_REG30   ", struct task_struct, thread.reg30);
-	offset("#define THREAD_REG31   ", struct task_struct, thread.reg31);
-	offset("#define THREAD_STATUS  ", struct task_struct, \
-	       thread.cp0_status);
-	offset("#define THREAD_FPU     ", struct task_struct, thread.fpu);
-	offset("#define THREAD_BVADDR  ", struct task_struct, \
-	       thread.cp0_badvaddr);
-	offset("#define THREAD_BUADDR  ", struct task_struct, \
-	       thread.cp0_baduaddr);
-	offset("#define THREAD_ECODE   ", struct task_struct, \
-	       thread.error_code);
-	offset("#define THREAD_TRAPNO  ", struct task_struct, thread.trap_no);
-	offset("#define THREAD_MFLAGS  ", struct task_struct, thread.mflags);
-	offset("#define THREAD_CURDS   ", struct task_struct, \
-	       thread.current_ds);
-	offset("#define THREAD_TRAMP   ", struct task_struct, \
-	       thread.irix_trampoline);
-	offset("#define THREAD_OLDCTX  ", struct task_struct, \
-	       thread.irix_oldctx);
-	linefeed;
-}
-
-void output_mm_defines(void)
-{
-	text("/* Linux mm_struct offsets. */");
-	offset("#define MM_USERS      ", struct mm_struct, mm_users);
-	offset("#define MM_PGD        ", struct mm_struct, pgd);
-	offset("#define MM_CONTEXT    ", struct mm_struct, context);
-	linefeed;
-}
-
-void output_sc_defines(void)
-{
-	text("/* Linux sigcontext offsets. */");
-	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
-	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
-	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
-	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
-	offset("#define SC_PC         ", struct sigcontext, sc_pc);
-	offset("#define SC_STATUS     ", struct sigcontext, sc_status);
-	offset("#define SC_OWNEDFP    ", struct sigcontext, sc_ownedfp);
-	offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
-	offset("#define SC_FPC_EIR    ", struct sigcontext, sc_fpc_eir);
-	offset("#define SC_CAUSE      ", struct sigcontext, sc_cause);
-	offset("#define SC_BADVADDR   ", struct sigcontext, sc_badvaddr);
-	linefeed;
-}
-
-text("#endif /* !(_MIPS_OFFSET_H) */");
diff -urN linux-2.4.20-pre6/arch/ppc/kernel/misc.S linux-2.4.20-pre7/arch/ppc/kernel/misc.S
--- linux-2.4.20-pre6/arch/ppc/kernel/misc.S	Thu Sep 12 20:01:32 2002
+++ linux-2.4.20-pre7/arch/ppc/kernel/misc.S	Thu Sep 12 20:01:41 2002
@@ -1159,6 +1159,30 @@
 	.long sys_mincore
 	.long sys_gettid
 	.long sys_tkill
+	.long sys_setxattr
+	.long sys_lsetxattr	/* 210 */
+	.long sys_fsetxattr
+	.long sys_getxattr
+	.long sys_lgetxattr
+	.long sys_fgetxattr
+	.long sys_listxattr	/* 215 */
+	.long sys_llistxattr
+	.long sys_flistxattr
+	.long sys_removexattr
+	.long sys_lremovexattr
+	.long sys_fremovexattr	/* 220  */
+	.long sys_ni_syscall 	/*	reserved for sys_futex */
+	.long sys_ni_syscall 	/*	reserved for sys_sched_setaffinity */
+	.long sys_ni_syscall 	/*	reserved for sys_sched_getaffinity */
+	.long sys_ni_syscall 	/*	reserved for sys_security */
+	.long sys_ni_syscall 	/* 225	reserved for Tux */
+	.long sys_ni_syscall 	/*	reserved for sys_sendfile64 */
+	.long sys_ni_syscall 	/*	reserved for sys_io_setup */
+	.long sys_ni_syscall 	/*	reserved for sys_io_destroy */
+	.long sys_ni_syscall 	/*	reserved for sys_io_getevents */
+	.long sys_ni_syscall 	/* 230	reserved for sys_io_submit */
+	.long sys_ni_syscall 	/*	reserved for sys_io_cancel */
+
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
 	.endr
diff -urN linux-2.4.20-pre6/drivers/block/rd.c linux-2.4.20-pre7/drivers/block/rd.c
--- linux-2.4.20-pre6/drivers/block/rd.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre7/drivers/block/rd.c	Thu Sep 12 20:01:42 2002
@@ -217,7 +217,7 @@
 		bh_kunmap(sbh);
 
 		if (rw == READ) {
-			flush_dcache_page(page);
+			flush_dcache_page(sbh->b_page);
 		} else {
 			SetPageDirty(page);
 		}
diff -urN linux-2.4.20-pre6/drivers/char/Makefile linux-2.4.20-pre7/drivers/char/Makefile
--- linux-2.4.20-pre6/drivers/char/Makefile	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/char/Makefile	Thu Sep 12 20:01:42 2002
@@ -24,7 +24,7 @@
 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 \
-			au1000_gpio.o hp_psaux.o
+			au1000_gpio.o hp_psaux.o nvram.o
 
 mod-subdirs	:=	joystick ftape drm drm-4.0 pcmcia
 
diff -urN linux-2.4.20-pre6/drivers/char/nvram.c linux-2.4.20-pre7/drivers/char/nvram.c
--- linux-2.4.20-pre6/drivers/char/nvram.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/char/nvram.c	Thu Sep 12 20:01:42 2002
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
  * idea by and with help from Richard Jelinek <rj@suse.de>
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com)
  *
  * This driver allows you to access the contents of the non-volatile memory in
  * the mc146818rtc.h real-time clock. This chip is built into all PCs and into
@@ -10,9 +11,10 @@
  * "NVRAM" (NV stands for non-volatile).
  *
  * The data are supplied as a (seekable) character device, /dev/nvram. The
- * size of this file is 50, the number of freely available bytes in the memory
- * (i.e., not used by the RTC itself).
- * 
+ * size of this file is dependant on the controller.  The usual size is 114,
+ * the number of freely available bytes in the memory (i.e., not used by the
+ * RTC itself).
+ *
  * Checksums over the NVRAM contents are managed by this driver. In case of a
  * bad checksum, reads and writes return -EIO. The checksum can be initialized
  * to a sane state either by ioctl(NVRAM_INIT) (clear whole NVRAM) or
@@ -28,25 +30,35 @@
  *
  * 	1.1	Cesar Barros: SMP locking fixes
  * 		added changelog
+ * 	1.2	Erik Gilling: Cobalt Networks support
+ * 		Tim Hockin: general cleanup, Cobalt support
  */
 
-#define NVRAM_VERSION		"1.1"
+#define NVRAM_VERSION	"1.2"
 
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+#include <linux/nvram.h>
 
 #define PC		1
 #define ATARI		2
+#define COBALT		3
 
 /* select machine configuration */
 #if defined(CONFIG_ATARI)
-#define MACH ATARI
+#  define MACH ATARI
 #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__)  /* and others?? */
 #define MACH PC
+#  if defined(CONFIG_COBALT)
+#    include <linux/cobalt-nvram.h>
+#    define MACH COBALT
+#  else
+#    define MACH PC
+#  endif
 #else
-#error Cannot build nvram driver for this machine configuration.
+#  error Cannot build nvram driver for this machine configuration.
 #endif
 
 #if MACH == PC
@@ -58,10 +70,23 @@
 #define PC_CKS_RANGE_START	2
 #define PC_CKS_RANGE_END	31
 #define PC_CKS_LOC		32
+#define NVRAM_BYTES		(128-NVRAM_FIRST_BYTE)
+
+#define mach_check_checksum	pc_check_checksum
+#define mach_set_checksum	pc_set_checksum
+#define mach_proc_infos		pc_proc_infos
+
+#endif
+
+#if MACH == COBALT
+
+#define CHECK_DRIVER_INIT()     1
+
+#define NVRAM_BYTES		(128-NVRAM_FIRST_BYTE)
 
-#define	mach_check_checksum	pc_check_checksum
-#define	mach_set_checksum	pc_set_checksum
-#define	mach_proc_infos		pc_proc_infos
+#define mach_check_checksum	cobalt_check_checksum
+#define mach_set_checksum	cobalt_set_checksum
+#define mach_proc_infos		cobalt_proc_infos
 
 #endif
 
@@ -79,9 +104,9 @@
 #define ATARI_CKS_RANGE_END	47
 #define ATARI_CKS_LOC		48
 
-#define	mach_check_checksum	atari_check_checksum
-#define	mach_set_checksum	atari_set_checksum
-#define	mach_proc_infos		atari_proc_infos
+#define mach_check_checksum	atari_check_checksum
+#define mach_set_checksum	atari_set_checksum
+#define mach_proc_infos		atari_proc_infos
 
 #endif
 
@@ -98,7 +123,6 @@
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/mc146818rtc.h>
-#include <linux/nvram.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
@@ -107,15 +131,11 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+static spinlock_t nvram_state_lock = SPIN_LOCK_UNLOCKED;
 static int nvram_open_cnt;	/* #times opened */
 static int nvram_open_mode;	/* special open modes */
-
-#define	NVRAM_WRITE		1	/* opened for writing (exclusive) */
-#define	NVRAM_EXCL		2	/* opened with O_EXCL */
-
-#define	RTC_FIRST_BYTE		14	/* RTC register number of first
-					 * NVRAM byte */
-#define	NVRAM_BYTES		128-RTC_FIRST_BYTE /* number of NVRAM bytes */
+#define NVRAM_WRITE		1 /* opened for writing (exclusive) */
+#define NVRAM_EXCL		2 /* opened with O_EXCL */
 
 static int mach_check_checksum(void);
 static void mach_set_checksum(void);
@@ -126,95 +146,85 @@
 #endif
 
 /*
- * These are the internal NVRAM access functions, which do NOT disable
- * interrupts and do not check the checksum. Both tasks are left to higher
- * level function, so they need to be done only once per syscall.
- */
-
-static __inline__ unsigned char
-nvram_read_int(int i)
-{
-	return CMOS_READ(RTC_FIRST_BYTE + i);
-}
-
-static __inline__ void
-nvram_write_int(unsigned char c, int i)
-{
-	CMOS_WRITE(c, RTC_FIRST_BYTE + i);
-}
-
-static __inline__ int
-nvram_check_checksum_int(void)
-{
-	return mach_check_checksum();
-}
-
-static __inline__ void
-nvram_set_checksum_int(void)
-{
-	mach_set_checksum();
-}
-
-#if MACH == ATARI
-
-/*
- * These non-internal functions are provided to be called by other parts of
+ * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
  * or after writing (needs to be done only once).
  *
- * They're only built if CONFIG_ATARI is defined, because Atari drivers use
- * them. For other configurations (PC), the rest of the kernel can't rely on
- * them being present (this driver may not be configured at all, or as a
- * module), so they access config information themselves.
+ * It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset.  Pass them offsets into NVRAM as if you did not 
+ * know about the RTC cruft.
  */
 
 unsigned char
+__nvram_read_byte(int i)
+{
+	return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char
 nvram_read_byte(int i)
 {
 	unsigned long flags;
 	unsigned char c;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	c = nvram_read_int(i);
+	c = __nvram_read_byte(i);
 	spin_unlock_irqrestore(&rtc_lock, flags);
 	return c;
 }
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
 void
+__nvram_write_byte(unsigned char c, int i)
+{
+	CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void
 nvram_write_byte(unsigned char c, int i)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	nvram_write_int(c, i);
+	__nvram_write_byte(c, i);
 	spin_unlock_irqrestore(&rtc_lock, flags);
 }
 
 int
+__nvram_check_checksum(void)
+{
+	return mach_check_checksum();
+}
+
+int
 nvram_check_checksum(void)
 {
 	unsigned long flags;
 	int rv;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	rv = nvram_check_checksum_int();
+	rv = __nvram_check_checksum();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 	return rv;
 }
 
 void
+__nvram_set_checksum(void)
+{
+	mach_set_checksum();
+}
+
+void
 nvram_set_checksum(void)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	nvram_set_checksum_int();
+	__nvram_set_checksum();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 }
 
-#endif /* MACH == ATARI */
-
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -239,17 +249,17 @@
 static ssize_t
 nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
-	char contents[NVRAM_BYTES];
+	unsigned char contents[NVRAM_BYTES];
 	unsigned i = *ppos;
-	char *tmp;
+	unsigned char *tmp;
 
 	spin_lock_irq(&rtc_lock);
 
-	if (!nvram_check_checksum_int())
+	if (!__nvram_check_checksum())
 		goto checksum_err;
 
 	for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-		*tmp = nvram_read_int(i);
+		*tmp = __nvram_read_byte(i);
 
 	spin_unlock_irq(&rtc_lock);
 
@@ -268,23 +278,24 @@
 static ssize_t
 nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-	char contents[NVRAM_BYTES];
+	unsigned char contents[NVRAM_BYTES];
 	unsigned i = *ppos;
-	char *tmp;
+	unsigned char *tmp;
+	int len;
 
-	if (copy_from_user(contents, buf, (NVRAM_BYTES - i) < count ?
-	    (NVRAM_BYTES - i) : count))
+	len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count;
+	if (copy_from_user(contents, buf, len))
 		return -EFAULT;
 
 	spin_lock_irq(&rtc_lock);
 
-	if (!nvram_check_checksum_int())
+	if (!__nvram_check_checksum())
 		goto checksum_err;
 
 	for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-		nvram_write_int(*tmp, i);
+		__nvram_write_byte(*tmp, i);
 
-	nvram_set_checksum_int();
+	__nvram_set_checksum();
 
 	spin_unlock_irq(&rtc_lock);
 
@@ -305,27 +316,28 @@
 
 	switch (cmd) {
 
-	case NVRAM_INIT:	/* initialize NVRAM contents and checksum */
+	case NVRAM_INIT:
+		/* initialize NVRAM contents and checksum */
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
 		spin_lock_irq(&rtc_lock);
 
 		for (i = 0; i < NVRAM_BYTES; ++i)
-			nvram_write_int(0, i);
-		nvram_set_checksum_int();
+			__nvram_write_byte(0, i);
+		__nvram_set_checksum();
 
 		spin_unlock_irq(&rtc_lock);
 		return 0;
 
-	case NVRAM_SETCKS:	/* just set checksum, contents unchanged
-				 * (maybe useful after checksum garbaged
-				 * somehow...) */
+	case NVRAM_SETCKS:
+		/* just set checksum, contents unchanged (maybe useful after 
+		 * checksum garbaged somehow...) */
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 
 		spin_lock_irq(&rtc_lock);
-		nvram_set_checksum_int();
+		__nvram_set_checksum();
 		spin_unlock_irq(&rtc_lock);
 		return 0;
 
@@ -337,29 +349,40 @@
 static int
 nvram_open(struct inode *inode, struct file *file)
 {
+	spin_lock(&nvram_state_lock);
+
 	if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
 	    (nvram_open_mode & NVRAM_EXCL) ||
-	    ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE)))
+	    ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) {
+		spin_unlock(&nvram_state_lock);
 		return -EBUSY;
+	}
 
 	if (file->f_flags & O_EXCL)
 		nvram_open_mode |= NVRAM_EXCL;
 	if (file->f_mode & 2)
 		nvram_open_mode |= NVRAM_WRITE;
 	nvram_open_cnt++;
+
+	spin_unlock(&nvram_state_lock);
+
 	return 0;
 }
 
 static int
 nvram_release(struct inode *inode, struct file *file)
 {
-	lock_kernel();
+	spin_lock(&nvram_state_lock);
+
 	nvram_open_cnt--;
-	if (file->f_flags & O_EXCL)
+
+	/* if only one instance is open, clear the EXCL bit */
+	if (nvram_open_mode & NVRAM_EXCL)
 		nvram_open_mode &= ~NVRAM_EXCL;
 	if (file->f_mode & 2)
 		nvram_open_mode &= ~NVRAM_WRITE;
-	unlock_kernel();
+
+	spin_unlock(&nvram_state_lock);
 
 	return 0;
 }
@@ -383,7 +406,7 @@
 
 	spin_lock_irq(&rtc_lock);
 	for (i = 0; i < NVRAM_BYTES; ++i)
-		contents[i] = nvram_read_int(i);
+		contents[i] = __nvram_read_byte(i);
 	spin_unlock_irq(&rtc_lock);
 
 	*eof = mach_proc_infos(contents, buffer, &len, &begin, offset, size);
@@ -397,7 +420,7 @@
 
 /* This macro frees the machine specific function from bounds checking and
  * this like that... */
-#define	PRINT_PROC(fmt,args...)					\
+#define PRINT_PROC(fmt,args...)					\
 	do {							\
 		*len += sprintf(buffer+*len, fmt, ##args);	\
 		if (*begin + *len > offset + size)		\
@@ -477,11 +500,13 @@
 {
 	int i;
 	unsigned short sum = 0;
+	unsigned short expect;
 
 	for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	return ((sum & 0xffff) ==
-	    ((nvram_read_int(PC_CKS_LOC)<<8) | nvram_read_int(PC_CKS_LOC+1)));
+		sum += __nvram_read_byte(i);
+	expect = __nvram_read_byte(PC_CKS_LOC)<<8 |
+	    __nvram_read_byte(PC_CKS_LOC+1);
+	return ((sum & 0xffff) == expect);
 }
 
 static void
@@ -491,9 +516,9 @@
 	unsigned short sum = 0;
 
 	for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	nvram_write_int(sum >> 8, PC_CKS_LOC);
-	nvram_write_int(sum & 0xff, PC_CKS_LOC + 1);
+		sum += __nvram_read_byte(i);
+	__nvram_write_byte(sum >> 8, PC_CKS_LOC);
+	__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -518,7 +543,7 @@
 	int type;
 
 	spin_lock_irq(&rtc_lock);
-	checksum = nvram_check_checksum_int();
+	checksum = __nvram_check_checksum();
 	spin_unlock_irq(&rtc_lock);
 
 	PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");
@@ -576,6 +601,177 @@
 
 #endif /* MACH == PC */
 
+#if MACH == COBALT
+
+/* the cobalt CMOS has a wider range of it's checksum */
+static int cobalt_check_checksum(void)
+{
+	int i;
+	unsigned short sum = 0;
+	unsigned short expect;
+
+	for (i = COBT_CMOS_CKS_START; i <= COBT_CMOS_CKS_END; ++i) {
+		if ((i == COBT_CMOS_CHECKSUM) || (i == (COBT_CMOS_CHECKSUM+1)))
+			continue;
+
+		sum += __nvram_read_byte(i);
+	}
+	expect = __nvram_read_byte(COBT_CMOS_CHECKSUM) << 8 |
+	    __nvram_read_byte(COBT_CMOS_CHECKSUM+1);
+	return ((sum & 0xffff) == expect);
+}
+
+static void cobalt_set_checksum(void)
+{
+	int i;
+	unsigned short sum = 0;
+
+	for (i = COBT_CMOS_CKS_START; i <= COBT_CMOS_CKS_END; ++i) {
+		if ((i == COBT_CMOS_CHECKSUM) || (i == (COBT_CMOS_CHECKSUM+1)))
+			continue;
+
+		sum += __nvram_read_byte(i);
+	}
+
+	__nvram_write_byte(sum >> 8, COBT_CMOS_CHECKSUM);
+	__nvram_write_byte(sum & 0xff, COBT_CMOS_CHECKSUM+1);
+}
+
+#ifdef CONFIG_PROC_FS
+
+static int cobalt_proc_infos(unsigned char *nvram, char *buffer, int *len,
+	off_t *begin, off_t offset, int size)
+{
+	int i;
+	unsigned int checksum;
+	unsigned int flags;
+	char sernum[14];
+	char *key = "cNoEbTaWlOtR!";
+	unsigned char bto_csum;
+
+	spin_lock_irq(&rtc_lock);
+	checksum = __nvram_check_checksum();
+	spin_unlock_irq(&rtc_lock);
+
+	PRINT_PROC("Checksum status: %svalid\n", checksum ? "" : "not ");
+
+	flags = nvram[COBT_CMOS_FLAG_BYTE_0] << 8 
+	    | nvram[COBT_CMOS_FLAG_BYTE_1];
+
+	PRINT_PROC("Console: %s\n",
+		flags & COBT_CMOS_CONSOLE_FLAG ?  "on": "off");
+
+	PRINT_PROC("Firmware Debug Messages: %s\n",
+		flags & COBT_CMOS_DEBUG_FLAG ? "on": "off");
+
+	PRINT_PROC("Auto Prompt: %s\n",
+		flags & COBT_CMOS_AUTO_PROMPT_FLAG ? "on": "off");
+
+	PRINT_PROC("Shutdown Status: %s\n",
+		flags & COBT_CMOS_CLEAN_BOOT_FLAG ? "clean": "dirty");
+
+	PRINT_PROC("Hardware Probe: %s\n",
+		flags & COBT_CMOS_HW_NOPROBE_FLAG ? "partial": "full");
+
+	PRINT_PROC("System Fault: %sdetected\n",
+		flags & COBT_CMOS_SYSFAULT_FLAG ? "": "not ");
+
+	PRINT_PROC("Panic on OOPS: %s\n",
+		flags & COBT_CMOS_OOPSPANIC_FLAG ? "yes": "no");
+
+	PRINT_PROC("Delayed Cache Initialization: %s\n",
+		flags & COBT_CMOS_DELAY_CACHE_FLAG ? "yes": "no");
+
+	PRINT_PROC("Show Logo at Boot: %s\n",
+		flags & COBT_CMOS_NOLOGO_FLAG ? "no": "yes");
+
+	PRINT_PROC("Boot Method: ");
+	switch (nvram[COBT_CMOS_BOOT_METHOD]) {
+	case COBT_CMOS_BOOT_METHOD_DISK:
+		PRINT_PROC("disk\n");
+		break;
+
+	case COBT_CMOS_BOOT_METHOD_ROM:
+		PRINT_PROC("rom\n");
+		break;
+
+	case COBT_CMOS_BOOT_METHOD_NET:
+		PRINT_PROC("net\n");
+		break;
+
+	default:
+		PRINT_PROC("unknown\n");
+		break;
+	}
+
+	PRINT_PROC("Primary Boot Device: %d:%d\n",
+		nvram[COBT_CMOS_BOOT_DEV0_MAJ],
+		nvram[COBT_CMOS_BOOT_DEV0_MIN] );
+	PRINT_PROC("Secondary Boot Device: %d:%d\n",
+		nvram[COBT_CMOS_BOOT_DEV1_MAJ],
+		nvram[COBT_CMOS_BOOT_DEV1_MIN] );
+	PRINT_PROC("Tertiary Boot Device: %d:%d\n",
+		nvram[COBT_CMOS_BOOT_DEV2_MAJ],
+		nvram[COBT_CMOS_BOOT_DEV2_MIN] );
+
+	PRINT_PROC("Uptime: %d\n",
+		nvram[COBT_CMOS_UPTIME_0] << 24 |
+		nvram[COBT_CMOS_UPTIME_1] << 16 |
+		nvram[COBT_CMOS_UPTIME_2] << 8  |
+		nvram[COBT_CMOS_UPTIME_3]);
+
+	PRINT_PROC("Boot Count: %d\n",
+		nvram[COBT_CMOS_BOOTCOUNT_0] << 24 |
+		nvram[COBT_CMOS_BOOTCOUNT_1] << 16 |
+		nvram[COBT_CMOS_BOOTCOUNT_2] << 8  |
+		nvram[COBT_CMOS_BOOTCOUNT_3]);
+
+	/* 13 bytes of serial num */
+	for (i=0 ; i<13 ; i++) {
+		sernum[i] = nvram[COBT_CMOS_SYS_SERNUM_0 + i];
+	}
+	sernum[13] = '\0';
+
+	checksum = 0;
+	for (i=0 ; i<13 ; i++) {
+		checksum += sernum[i] ^ key[i];
+	}
+	checksum = ((checksum & 0x7f) ^ (0xd6)) & 0xff;
+
+	PRINT_PROC("Serial Number: %s", sernum);
+	if (checksum != nvram[COBT_CMOS_SYS_SERNUM_CSUM]) {
+		PRINT_PROC(" (invalid checksum)");
+	}
+	PRINT_PROC("\n");
+
+	PRINT_PROC("Rom Revison: %d.%d.%d\n", nvram[COBT_CMOS_ROM_REV_MAJ],
+		nvram[COBT_CMOS_ROM_REV_MIN], nvram[COBT_CMOS_ROM_REV_REV]);
+
+	PRINT_PROC("BTO Server: %d.%d.%d.%d", nvram[COBT_CMOS_BTO_IP_0],
+		nvram[COBT_CMOS_BTO_IP_1], nvram[COBT_CMOS_BTO_IP_2],
+		nvram[COBT_CMOS_BTO_IP_3]);
+	bto_csum = nvram[COBT_CMOS_BTO_IP_0] + nvram[COBT_CMOS_BTO_IP_1]
+		+ nvram[COBT_CMOS_BTO_IP_2] + nvram[COBT_CMOS_BTO_IP_3];
+	if (bto_csum != nvram[COBT_CMOS_BTO_IP_CSUM]) {
+		PRINT_PROC(" (invalid checksum)");
+	}
+	PRINT_PROC("\n");
+
+	if (flags & COBT_CMOS_VERSION_FLAG
+	 && nvram[COBT_CMOS_VERSION] >= COBT_CMOS_VER_BTOCODE) {
+		PRINT_PROC("BTO Code: 0x%x\n",
+			nvram[COBT_CMOS_BTO_CODE_0] << 24 |
+			nvram[COBT_CMOS_BTO_CODE_1] << 16 |
+			nvram[COBT_CMOS_BTO_CODE_2] << 8 |
+			nvram[COBT_CMOS_BTO_CODE_3]);
+	}
+
+	return 1;
+}
+#endif /* CONFIG_PROC_FS */
+
+#endif /* MACH == COBALT */
+
 #if MACH == ATARI
 
 static int
@@ -585,9 +781,9 @@
 	unsigned char sum = 0;
 
 	for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	return (nvram_read_int(ATARI_CKS_LOC) == (~sum & 0xff) &&
-	    nvram_read_int(ATARI_CKS_LOC + 1) == (sum & 0xff));
+		sum += __nvram_read_byte(i);
+	return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff) &&
+	    __nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
 static void
@@ -597,9 +793,9 @@
 	unsigned char sum = 0;
 
 	for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
-		sum += nvram_read_int(i);
-	nvram_write_int(~sum, ATARI_CKS_LOC);
-	nvram_write_int(sum, ATARI_CKS_LOC + 1);
+		sum += __nvram_read_byte(i);
+	__nvram_write_byte(~sum, ATARI_CKS_LOC);
+	__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -716,4 +912,11 @@
 
 MODULE_LICENSE("GPL");
 
-EXPORT_NO_SYMBOLS;
+EXPORT_SYMBOL(__nvram_read_byte);
+EXPORT_SYMBOL(nvram_read_byte);
+EXPORT_SYMBOL(__nvram_write_byte);
+EXPORT_SYMBOL(nvram_write_byte);
+EXPORT_SYMBOL(__nvram_check_checksum);
+EXPORT_SYMBOL(nvram_check_checksum);
+EXPORT_SYMBOL(__nvram_set_checksum);
+EXPORT_SYMBOL(nvram_set_checksum);
diff -urN linux-2.4.20-pre6/drivers/char/vt.c linux-2.4.20-pre7/drivers/char/vt.c
--- linux-2.4.20-pre6/drivers/char/vt.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/char/vt.c	Thu Sep 12 20:01:43 2002
@@ -90,7 +90,7 @@
  * comments - KDMKTONE doesn't put the process to sleep.
  */
 
-#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
+#if defined(__i386__) || defined(__alpha__) || defined(CONFIG_PPC_ISATIMER) \
     || (defined(__mips__) && defined(CONFIG_ISA)) \
     || (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE)) \
     || defined(__x86_64__)
diff -urN linux-2.4.20-pre6/drivers/ide/Config.in linux-2.4.20-pre7/drivers/ide/Config.in
--- linux-2.4.20-pre6/drivers/ide/Config.in	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/ide/Config.in	Thu Sep 12 20:01:43 2002
@@ -72,7 +72,7 @@
   	    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/368/370 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
-	    if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then
+	    if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" -o "$CONFIG_MIPS" = "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
 	    fi
@@ -108,7 +108,7 @@
 	 fi
       fi
       if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
-	 bool '  SWARM onboard IDE support' CONFIG_BLK_DEV_IDE_SWARM
+	 bool '  Broadcom SiByte onboard IDE support' CONFIG_BLK_DEV_IDE_SIBYTE
       fi
       if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
 	 dep_bool '    ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN
diff -urN linux-2.4.20-pre6/drivers/ide/Makefile linux-2.4.20-pre7/drivers/ide/Makefile
--- linux-2.4.20-pre6/drivers/ide/Makefile	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/ide/Makefile	Thu Sep 12 20:01:43 2002
@@ -49,7 +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_IDE_SIBYTE)	+= ide-sibyte.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
diff -urN linux-2.4.20-pre6/drivers/ide/ide-pci.c linux-2.4.20-pre7/drivers/ide/ide-pci.c
--- linux-2.4.20-pre6/drivers/ide/ide-pci.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/ide/ide-pci.c	Thu Sep 12 20:01:43 2002
@@ -628,7 +628,7 @@
 			printk(KERN_WARNING "%s: (ide_setup_pci_device:) Could not enable device.\n", d->name);
 			return;
 		}
-		printk(KERN_INFO "%s: BIOS setup was incomplete.\n");
+		printk(KERN_INFO "%s: BIOS setup was incomplete.\n", d->name);
 	}
 
 check_if_enabled:
diff -urN linux-2.4.20-pre6/drivers/ide/ide-sibyte.c linux-2.4.20-pre7/drivers/ide/ide-sibyte.c
--- linux-2.4.20-pre6/drivers/ide/ide-sibyte.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/ide/ide-sibyte.c	Thu Sep 12 20:01:43 2002
@@ -0,0 +1,333 @@
+/*
+ * 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_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/64bit.h>
+#include <asm/sibyte/board.h>
+
+/* Note: this should be general for any board using IDE on GenBus */
+
+extern struct ide_ops std_ide_ops;
+
+static ide_hwif_t *sb_ide_hwif = NULL;
+static unsigned long ide_base;
+
+#define SIBYTE_IDE_BASE        (KSEG1ADDR(ide_base)-mips_io_port_base)
+#define SIBYTE_IDE_REG(pcaddr) (SIBYTE_IDE_BASE + ((pcaddr)<<5))
+
+/*
+ * We are limiting the number of PCI-IDE devices to leave room for
+ * GenBus IDE (and possibly PCMCIA/CF?)
+ */
+static int sibyte_ide_default_irq(ide_ioreg_t base)
+{
+	return 0;
+}
+
+static ide_ioreg_t sibyte_ide_default_io_base(int index)
+{
+	return 0;
+}
+
+static void sibyte_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
+				       ide_ioreg_t ctrl_port, int *irq)
+{
+	std_ide_ops.ide_init_hwif_ports(hw, data_port, ctrl_port, irq);
+}
+
+static int sibyte_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 sibyte_ide_free_irq(unsigned int irq, void *dev_id)
+{
+	free_irq(irq, dev_id);
+}
+
+static inline int is_sibyte_ide(ide_ioreg_t from)
+{
+	return (sb_ide_hwif &&
+		((from == sb_ide_hwif->io_ports[IDE_DATA_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_ERROR_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_NSECTOR_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_SECTOR_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_LCYL_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_HCYL_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_SELECT_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_STATUS_OFFSET]) ||
+		 (from == sb_ide_hwif->io_ports[IDE_CONTROL_OFFSET])));
+}
+
+static int sibyte_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+	/* Figure out if it's the SiByte IDE; if so, don't do anything
+           since our I/O space is in a weird place. */
+	if (is_sibyte_ide(from))
+		return 0;
+	else
+#ifdef CONFIG_BLK_DEV_IDE
+		return std_ide_ops.ide_check_region(from, extent);
+#else
+		return 0;
+#endif
+}
+
+static void sibyte_ide_request_region(ide_ioreg_t from, unsigned int extent,
+				     const char *name)
+{
+#ifdef CONFIG_BLK_DEV_IDE
+	if (!is_sibyte_ide(from))
+		std_ide_ops.ide_request_region(from, extent, name);
+#endif
+}
+
+static void sibyte_ide_release_region(ide_ioreg_t from, unsigned int extent)
+{
+#ifdef CONFIG_BLK_DEV_IDE
+	if (!is_sibyte_ide(from))
+		std_ide_ops.ide_release_region(from, extent);
+#endif
+}
+
+struct ide_ops sibyte_ide_ops = {
+	&sibyte_ide_default_irq,
+	&sibyte_ide_default_io_base,
+	&sibyte_ide_init_hwif_ports,
+	&sibyte_ide_request_irq,
+	&sibyte_ide_free_irq,
+	&sibyte_ide_check_region,
+	&sibyte_ide_request_region,
+	&sibyte_ide_release_region
+};
+
+/*
+ * I/O operations. The FPGA for SiByte generic bus IDE deals with
+ * byte-swapping for us, so we can't share the I/O macros with other
+ * IDE (e.g. PCI-IDE) devices.
+ */
+
+#define sibyte_outb(val,port)					\
+do {								\
+	*(volatile u8 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+#define sibyte_outw(val,port)					\
+do {								\
+	*(volatile u16 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+#define sibyte_outl(val,port)					\
+do {								\
+	*(volatile u32 *)(mips_io_port_base + (port)) = val;	\
+} while(0)
+
+static inline unsigned char sibyte_inb(unsigned long port)
+{
+	return (*(volatile u8 *)(mips_io_port_base + (port)));
+}
+
+static inline unsigned short sibyte_inw(unsigned long port)
+{
+	return (*(volatile u16 *)(mips_io_port_base + (port)));
+}
+
+static inline unsigned int sibyte_inl(unsigned long port)
+{
+	return (*(volatile u32 *)(mips_io_port_base + (port)));
+}
+
+
+static inline void sibyte_outsb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		sibyte_outb(*(u8 *)addr, port);
+		addr++;
+	}
+}
+
+static inline void sibyte_insb(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u8 *)addr = sibyte_inb(port);
+		addr++;
+	}
+}
+
+static inline void sibyte_outsw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		sibyte_outw(*(u16 *)addr, port);
+		addr += 2;
+	}
+}
+
+static inline void sibyte_insw(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u16 *)addr = sibyte_inw(port);
+		addr += 2;
+	}
+}
+
+static inline void sibyte_outsl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		sibyte_outl(*(u32 *)addr, port);
+		addr += 4;
+	}
+}
+
+static inline void sibyte_insl(unsigned long port, void *addr, unsigned int count)
+{
+	while (count--) {
+		*(u32 *)addr = sibyte_inl(port);
+		addr += 4;
+	}
+}
+
+static void sibyte_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) {
+			sibyte_insl(IDE_DATA_REG, buffer, count);
+		} else {
+			sibyte_insw(IDE_DATA_REG, buffer, count<<1);
+		}
+		break;
+	case ideproc_ide_output_data:
+		if (drive->io_32bit) {
+			sibyte_outsl(IDE_DATA_REG, buffer, count);
+		} else {
+			sibyte_outsw(IDE_DATA_REG, buffer, count<<1);
+		}
+		break;
+	case ideproc_atapi_input_bytes:
+		count++;
+		if (drive->io_32bit) {
+			sibyte_insl(IDE_DATA_REG, buffer, count>>2);
+		} else {
+			sibyte_insw(IDE_DATA_REG, buffer, count>>1);
+		}
+		if ((count & 3) >= 2)
+			sibyte_insw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1);
+		break;
+	case ideproc_atapi_output_bytes:
+		count++;
+		if (drive->io_32bit) {
+			sibyte_outsl(IDE_DATA_REG, buffer, count>>2);
+		} else {
+			sibyte_outsw(IDE_DATA_REG, buffer, count>>1);
+		}
+		if ((count & 3) >= 2)
+			sibyte_outsw(IDE_DATA_REG, (char *)buffer + (count & ~3), 1);
+		break;
+	}
+}
+
+/*
+ * selectproc and intrproc aren't really necessary, since
+ * byte-swapping doesn't affect byte ops; they are included for
+ * consistency.
+ */
+static void sibyte_selectproc(ide_drive_t *drive)
+{
+	sibyte_outb(drive->select.all, IDE_SELECT_REG);
+}
+
+static void sibyte_intrproc(ide_drive_t *drive)
+{
+	sibyte_outb(drive->ctl|2, IDE_CONTROL_REG);
+}
+
+void __init sibyte_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 SiByte onboard IDE driver in ide_hwifs[].  Not enabled.\n");
+		return;
+	}
+
+	/* Find memory base address */
+#ifdef __MIPSEL__
+	/* Pass1 workaround (bug 1624) */
+	if (sb1250_pass == K_SYS_REVISION_PASS1)
+		ide_base = G_IO_START_ADDR(csr_in32(4+(IO_SPACE_BASE|A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS))))) << S_IO_ADDRBASE;
+	else
+#endif
+		ide_base = G_IO_START_ADDR(csr_in32(IO_SPACE_BASE|A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)))) << S_IO_ADDRBASE;
+
+	/*
+	 * Set up our stuff; we're a little odd because our io_ports
+	 * aren't in the usual place, and byte-swapping isn't
+	 * necessary.
+	 */
+	hwif = &ide_hwifs[i];
+	hwif->hw.io_ports[IDE_DATA_OFFSET]    = SIBYTE_IDE_REG(0x1f0);
+	hwif->hw.io_ports[IDE_ERROR_OFFSET]   = SIBYTE_IDE_REG(0x1f1);
+	hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f2);
+	hwif->hw.io_ports[IDE_SECTOR_OFFSET]  = SIBYTE_IDE_REG(0x1f3);
+	hwif->hw.io_ports[IDE_LCYL_OFFSET]    = SIBYTE_IDE_REG(0x1f4);
+	hwif->hw.io_ports[IDE_HCYL_OFFSET]    = SIBYTE_IDE_REG(0x1f5);
+	hwif->hw.io_ports[IDE_SELECT_OFFSET]  = SIBYTE_IDE_REG(0x1f6);
+	hwif->hw.io_ports[IDE_STATUS_OFFSET]  = SIBYTE_IDE_REG(0x1f7);
+	hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SIBYTE_IDE_REG(0x3f6);
+	hwif->hw.irq                          = K_INT_GB_IDE;
+	hwif->irq                             = K_INT_GB_IDE;
+	hwif->noprobe                         = 0;
+	/* Use our own non-byte-swapping routines */
+	hwif->ideproc                         = sibyte_ideproc;
+	hwif->selectproc                      = sibyte_selectproc;
+	hwif->intrproc                        = sibyte_intrproc;
+
+	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+	printk("SiByte onboard IDE configured as device %i\n", i);
+	sb_ide_hwif = hwif;
+}
diff -urN linux-2.4.20-pre6/drivers/ide/ide-swarm.c linux-2.4.20-pre7/drivers/ide/ide-swarm.c
--- linux-2.4.20-pre6/drivers/ide/ide-swarm.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/ide/ide-swarm.c	Wed Dec 31 16:00:00 1969
@@ -1,73 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/drivers/ide/ide.c linux-2.4.20-pre7/drivers/ide/ide.c
--- linux-2.4.20-pre6/drivers/ide/ide.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/ide/ide.c	Thu Sep 12 20:01:43 2002
@@ -3620,12 +3620,12 @@
 		pmac_ide_probe();
 	}
 #endif /* CONFIG_BLK_DEV_IDE_PMAC */
-#ifdef CONFIG_BLK_DEV_IDE_SWARM
+#ifdef CONFIG_BLK_DEV_IDE_SIBYTE
 	{
-		extern void swarm_ide_probe(void);
-		swarm_ide_probe();
+		extern void sibyte_ide_probe(void);
+		sibyte_ide_probe();
 	}
-#endif /* CONFIG_BLK_DEV_IDE_SWARM */
+#endif /* CONFIG_BLK_DEV_IDE_SIBYTE */
 #ifdef CONFIG_BLK_DEV_IDE_ICSIDE
 	{
 		extern void icside_init(void);
diff -urN linux-2.4.20-pre6/drivers/mtd/devices/Config.in linux-2.4.20-pre7/drivers/mtd/devices/Config.in
--- linux-2.4.20-pre6/drivers/mtd/devices/Config.in	Thu Oct  4 15:13:18 2001
+++ linux-2.4.20-pre7/drivers/mtd/devices/Config.in	Thu Sep 12 20:01:43 2002
@@ -10,6 +10,7 @@
    bool '    PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
    bool '    PMC551 Debugging' CONFIG_MTD_PMC551_DEBUG
 fi
+dep_tristate '  DEC MS02-NV NVRAM module support' CONFIG_MTD_MS02NV $CONFIG_MTD $CONFIG_DECSTATION
 dep_tristate '  Uncached system RAM' CONFIG_MTD_SLRAM $CONFIG_MTD
 if [ "$CONFIG_SA1100_LART" = "y" ]; then
   dep_tristate '  28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD
diff -urN linux-2.4.20-pre6/drivers/mtd/devices/Makefile linux-2.4.20-pre7/drivers/mtd/devices/Makefile
--- linux-2.4.20-pre6/drivers/mtd/devices/Makefile	Thu Oct  4 15:13:18 2001
+++ linux-2.4.20-pre7/drivers/mtd/devices/Makefile	Thu Sep 12 20:01:43 2002
@@ -18,6 +18,7 @@
 obj-$(CONFIG_MTD_DOCPROBE)	+= docprobe.o docecc.o
 obj-$(CONFIG_MTD_SLRAM)		+= slram.o
 obj-$(CONFIG_MTD_PMC551)	+= pmc551.o
+obj-$(CONFIG_MTD_MS02NV)	+= ms02-nv.o
 obj-$(CONFIG_MTD_MTDRAM)	+= mtdram.o
 obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLKMTD)	+= blkmtd.o
diff -urN linux-2.4.20-pre6/drivers/mtd/devices/ms02-nv.c linux-2.4.20-pre7/drivers/mtd/devices/ms02-nv.c
--- linux-2.4.20-pre6/drivers/mtd/devices/ms02-nv.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/mtd/devices/ms02-nv.c	Thu Sep 12 20:01:43 2002
@@ -0,0 +1,323 @@
+/*
+ *      Copyright (c) 2001 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/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn03.h>
+#include <asm/io.h>
+#include <asm/paccess.h>
+
+#include "ms02-nv.h"
+
+
+static char version[] __initdata =
+        "ms02-nv.c: v.1.0.0  13 Aug 2001  Maciej W. Rozycki.\n";
+
+MODULE_AUTHOR("Maciej W. Rozycki <macro@ds2.pg.gda.pl>");
+MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * Addresses we probe for an MS02-NV at.  Modules may be located
+ * at any 8MB boundary within a 0MB up to 112MB range or at any 32MB
+ * boundary within a 0MB up to 448MB range.  We don't support a module
+ * at 0MB, though.
+ */
+static ulong ms02nv_addrs[] __initdata = {
+	0x07000000, 0x06800000, 0x06000000, 0x05800000, 0x05000000,
+	0x04800000, 0x04000000, 0x03800000, 0x03000000, 0x02800000,
+	0x02000000, 0x01800000, 0x01000000, 0x00800000
+};
+
+static const char ms02nv_name[] = "DEC MS02-NV NVRAM";
+static const char ms02nv_res_diag_ram[] = "Diagnostic RAM";
+static const char ms02nv_res_user_ram[] = "General-purpose RAM";
+static const char ms02nv_res_csr[] = "Control and status register";
+
+static struct mtd_info *root_ms02nv_mtd;
+
+
+static int ms02nv_read(struct mtd_info *mtd, loff_t from,
+			size_t len, size_t *retlen, u_char *buf)
+{
+	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+	if (from + len > mtd->size)
+		return -EINVAL;
+
+	memcpy(buf, mp->uaddr + from, len);
+	*retlen = len;
+
+	return 0;
+}
+
+static int ms02nv_write(struct mtd_info *mtd, loff_t to,
+			size_t len, size_t *retlen, const u_char *buf)
+{
+	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+	if (to + len > mtd->size)
+		return -EINVAL;
+
+	memcpy(mp->uaddr + to, buf, len);
+	*retlen = len;
+
+	return 0;
+}
+
+
+static inline uint ms02nv_probe_one(ulong addr)
+{
+	ms02nv_uint *ms02nv_diagp;
+	ms02nv_uint *ms02nv_magicp;
+	uint ms02nv_diag;
+	uint ms02nv_magic;
+	size_t size;
+
+	int err;
+
+	/*
+	 * The firmware writes MS02NV_ID at MS02NV_MAGIC and also
+	 * a diagnostic status at MS02NV_DIAG.
+	 */
+	ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG));
+	ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC));
+	err = get_dbe(ms02nv_magic, ms02nv_magicp);
+	if (err)
+		return 0;
+	if (ms02nv_magic != MS02NV_ID)
+		return 0;
+
+	ms02nv_diag = *ms02nv_diagp;
+	size = (ms02nv_diag & MS02NV_DIAG_SIZE_MASK) << MS02NV_DIAG_SIZE_SHIFT;
+	if (size > MS02NV_CSR)
+		size = MS02NV_CSR;
+
+	return size;
+}
+
+static int __init ms02nv_init_one(ulong addr)
+{
+	struct mtd_info *mtd;
+	struct ms02nv_private *mp;
+	struct resource *mod_res;
+	struct resource *diag_res;
+	struct resource *user_res;
+	struct resource *csr_res;
+	ulong fixaddr;
+	size_t size, fixsize;
+
+	static int version_printed;
+
+	int ret = -ENODEV;
+
+	/* The module decodes 8MB of address space. */
+	mod_res = kmalloc(sizeof(*mod_res), GFP_KERNEL);
+	if (!mod_res)
+		return -ENOMEM;
+
+	memset(mod_res, 0, sizeof(*mod_res));
+	mod_res->name = ms02nv_name;
+	mod_res->start = addr;
+	mod_res->end = addr + MS02NV_SLOT_SIZE - 1;
+	mod_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	if (request_resource(&iomem_resource, mod_res) < 0)
+		goto err_out_mod_res;
+
+	size = ms02nv_probe_one(addr);
+	if (!size)
+		goto err_out_mod_res_rel;
+
+	if (!version_printed) {
+		printk(KERN_INFO "%s", version);
+		version_printed = 1;
+	}
+
+	ret = -ENOMEM;
+	mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+	if (!mtd)
+		goto err_out_mod_res_rel;
+	memset(mtd, 0, sizeof(*mtd));
+	mp = kmalloc(sizeof(*mp), GFP_KERNEL);
+	if (!mp)
+		goto err_out_mtd;
+	memset(mp, 0, sizeof(*mp));
+
+	mtd->priv = mp;
+	mp->resource.module = mod_res;
+
+	/* Firmware's diagnostic NVRAM area. */
+	diag_res = kmalloc(sizeof(*diag_res), GFP_KERNEL);
+	if (!diag_res)
+		goto err_out_mp;
+
+	memset(diag_res, 0, sizeof(*diag_res));
+	diag_res->name = ms02nv_res_diag_ram;
+	diag_res->start = addr;
+	diag_res->end = addr + MS02NV_RAM - 1;
+	diag_res->flags = IORESOURCE_BUSY;
+	request_resource(mod_res, diag_res);
+
+	mp->resource.diag_ram = diag_res;
+
+	/* User-available general-purpose NVRAM area. */
+	user_res = kmalloc(sizeof(*user_res), GFP_KERNEL);
+	if (!user_res)
+		goto err_out_diag_res;
+
+	memset(user_res, 0, sizeof(*user_res));
+	user_res->name = ms02nv_res_user_ram;
+	user_res->start = addr + MS02NV_RAM;
+	user_res->end = addr + size - 1;
+	user_res->flags = IORESOURCE_BUSY;
+	request_resource(mod_res, user_res);
+
+	mp->resource.user_ram = user_res;
+
+	/* Control and status register. */
+	csr_res = kmalloc(sizeof(*csr_res), GFP_KERNEL);
+	if (!csr_res)
+		goto err_out_user_res;
+
+	memset(csr_res, 0, sizeof(*csr_res));
+	csr_res->name = ms02nv_res_csr;
+	csr_res->start = addr + MS02NV_CSR;
+	csr_res->end = addr + MS02NV_CSR + 3;
+	csr_res->flags = IORESOURCE_BUSY;
+	request_resource(mod_res, csr_res);
+
+	mp->resource.csr = csr_res;
+
+	mp->addr = phys_to_virt(addr);
+	mp->size = size;
+
+	/*
+	 * Hide the firmware's diagnostic area.  It may get destroyed
+	 * upon a reboot.  Take paging into account for mapping support.
+	 */
+	fixaddr = (addr + MS02NV_RAM + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+	fixsize = (size - (fixaddr - addr)) & ~(PAGE_SIZE - 1);
+	mp->uaddr = phys_to_virt(fixaddr);
+
+	mtd->type = MTD_RAM;
+	mtd->flags = MTD_CAP_RAM | MTD_XIP;
+	mtd->size = fixsize;
+	mtd->name = (char *)ms02nv_name;
+	mtd->module = THIS_MODULE;
+	mtd->read = ms02nv_read;
+	mtd->write = ms02nv_write;
+
+	ret = -EIO;
+	if (add_mtd_device(mtd)) {
+		printk(KERN_ERR
+			"ms02-nv: Unable to register MTD device, aborting!\n");
+		goto err_out_csr_res;
+	}
+
+	printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMB.\n",
+		mtd->index, ms02nv_name, addr, size >> 20);
+
+	mp->next = root_ms02nv_mtd;
+	root_ms02nv_mtd = mtd;
+
+	return 0;
+
+
+err_out_csr_res:
+	release_resource(csr_res);
+	kfree(csr_res);
+err_out_user_res:
+	release_resource(user_res);
+	kfree(user_res);
+err_out_diag_res:
+	release_resource(diag_res);
+	kfree(diag_res);
+err_out_mp:
+	kfree(mp);
+err_out_mtd:
+	kfree(mtd);
+err_out_mod_res_rel:
+	release_resource(mod_res);
+err_out_mod_res:
+	kfree(mod_res);
+	return ret;
+}
+
+static void __exit ms02nv_remove_one(void)
+{
+	struct mtd_info *mtd = root_ms02nv_mtd;
+	struct ms02nv_private *mp = (struct ms02nv_private *)mtd->priv;
+
+	root_ms02nv_mtd = mp->next;
+
+	del_mtd_device(mtd);
+
+	release_resource(mp->resource.csr);
+	kfree(mp->resource.csr);
+	release_resource(mp->resource.user_ram);
+	kfree(mp->resource.user_ram);
+	release_resource(mp->resource.diag_ram);
+	kfree(mp->resource.diag_ram);
+	release_resource(mp->resource.module);
+	kfree(mp->resource.module);
+	kfree(mp);
+	kfree(mtd);
+}
+
+
+static int __init ms02nv_init(void)
+{
+	volatile u32 *csr;
+	uint stride = 0;
+	int count = 0;
+	int i;
+
+	switch (mips_machtype) {
+	case MACH_DS5000_200:
+		csr = (volatile u32 *)KN02_CSR_ADDR;
+		if (*csr & KN02_CSR_BNK32M)
+			stride = 2;
+		break;
+	case MACH_DS5000_2X0:
+		csr = (volatile u32 *)KN03_MCR_BASE;
+		if (*csr & KN03_MCR_BNK32M)
+			stride = 2;
+		break;
+	default:
+		return -ENODEV;
+		break;
+	}
+
+	for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++)
+		if (!ms02nv_init_one(ms02nv_addrs[i] << stride))
+			count++;
+
+	return (count > 0) ? 0 : -ENODEV;
+}
+
+static void __exit ms02nv_cleanup(void)
+{
+	while (root_ms02nv_mtd)
+		ms02nv_remove_one();
+}
+
+
+module_init(ms02nv_init);
+module_exit(ms02nv_cleanup);
diff -urN linux-2.4.20-pre6/drivers/mtd/devices/ms02-nv.h linux-2.4.20-pre7/drivers/mtd/devices/ms02-nv.h
--- linux-2.4.20-pre6/drivers/mtd/devices/ms02-nv.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/mtd/devices/ms02-nv.h	Thu Sep 12 20:01:43 2002
@@ -0,0 +1,43 @@
+/*
+ *      Copyright (c) 2001 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/ioport.h>
+#include <linux/mtd/mtd.h>
+
+/* MS02-NV iomem register offsets. */
+#define MS02NV_CSR		0x400000	/* control & status register */
+
+/* MS02-NV memory offsets. */
+#define MS02NV_DIAG		0x0003f8	/* diagnostic status */
+#define MS02NV_MAGIC		0x0003fc	/* MS02-NV magic ID */
+#define MS02NV_RAM		0x000400	/* general-purpose RAM start */
+
+/* MS02-NV diagnostic status constants. */
+#define MS02NV_DIAG_SIZE_MASK	0xf0		/* RAM size mask */
+#define MS02NV_DIAG_SIZE_SHIFT	0x10		/* RAM size shift (left) */
+
+/* MS02-NV general constants. */
+#define MS02NV_ID		0x03021966	/* MS02-NV magic ID value */
+#define MS02NV_SLOT_SIZE	0x800000	/* size of the address space
+						   decoded by the module */
+
+typedef volatile u32 ms02nv_uint;
+
+struct ms02nv_private {
+	struct mtd_info *next;
+	struct {
+		struct resource *module;
+		struct resource *diag_ram;
+		struct resource *user_ram;
+		struct resource *csr;
+	} resource;
+	u_char *addr;
+	size_t size;
+	u_char *uaddr;
+};
diff -urN linux-2.4.20-pre6/drivers/mtd/maps/Config.in linux-2.4.20-pre7/drivers/mtd/maps/Config.in
--- linux-2.4.20-pre6/drivers/mtd/maps/Config.in	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/mtd/maps/Config.in	Thu Sep 12 20:01:43 2002
@@ -46,9 +46,11 @@
 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
+   dep_tristate '  Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
+   if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \
+	-o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then
+      bool '  Pb1[015]00 boot flash device' CONFIG_MTD_PB1500_BOOT 
+      bool '  Pb1[015]00 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
diff -urN linux-2.4.20-pre6/drivers/mtd/maps/Makefile linux-2.4.20-pre7/drivers/mtd/maps/Makefile
--- linux-2.4.20-pre6/drivers/mtd/maps/Makefile	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/mtd/maps/Makefile	Thu Sep 12 20:01:43 2002
@@ -37,7 +37,8 @@
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)		+= pci.o
 obj-$(CONFIG_MTD_PB1000)        += pb1xxx-flash.o
+obj-$(CONFIG_MTD_PB1100)        += pb1xxx-flash.o
 obj-$(CONFIG_MTD_PB1500)        += pb1xxx-flash.o
-obj-$(CONFIG_MTD_AUTCPU12)      += autcpu12-nvram.o
+obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.20-pre6/drivers/mtd/maps/pb1xxx-flash.c linux-2.4.20-pre7/drivers/mtd/maps/pb1xxx-flash.c
--- linux-2.4.20-pre6/drivers/mtd/maps/pb1xxx-flash.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/mtd/maps/pb1xxx-flash.c	Thu Sep 12 20:01:43 2002
@@ -3,7 +3,7 @@
  * 
  * (C) 2001 Pete Popov <ppopov@mvista.com>
  * 
- * $Id: pb1xxx-flash.c,v 1.2 2002/02/14 19:36:45 ppopov Exp $
+ * $Id: pb1xxx-flash.c,v 1.5 2002/02/01 23:08:50 ppopov Exp $
  */
 
 #include <linux/config.h>
@@ -127,7 +127,7 @@
         }
 };
 
-#elif defined(CONFIG_MIPS_PB1500)
+#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
 
 static unsigned char flash_buswidth = 4;
 #if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
diff -urN linux-2.4.20-pre6/drivers/net/Config.in linux-2.4.20-pre7/drivers/net/Config.in
--- linux-2.4.20-pre6/drivers/net/Config.in	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/Config.in	Thu Sep 12 20:01:43 2002
@@ -67,6 +67,9 @@
    if [ "$CONFIG_SGI_IP27" = "y" ]; then
       bool '  SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH
    fi
+   if [ "$CONFIG_SGI_IP32" = "y" ]; then
+      tristate '  SGI O2 MACE Fast Ethernet support' CONFIG_SGI_O2MACE_ETH
+   fi
    if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then
       bool '  SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH
    fi
diff -urN linux-2.4.20-pre6/drivers/net/Makefile linux-2.4.20-pre7/drivers/net/Makefile
--- linux-2.4.20-pre6/drivers/net/Makefile	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/Makefile	Thu Sep 12 20:01:43 2002
@@ -166,6 +166,7 @@
 obj-$(CONFIG_SUN3LANCE) += sun3lance.o
 obj-$(CONFIG_DEFXX) += defxx.o
 obj-$(CONFIG_SGISEEQ) += sgiseeq.o
+obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
 obj-$(CONFIG_AT1700) += at1700.o
 obj-$(CONFIG_FMV18X) += fmv18x.o
 obj-$(CONFIG_EL1) += 3c501.o
diff -urN linux-2.4.20-pre6/drivers/net/au1000_eth.c linux-2.4.20-pre7/drivers/net/au1000_eth.c
--- linux-2.4.20-pre6/drivers/net/au1000_eth.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/au1000_eth.c	Thu Sep 12 20:01:44 2002
@@ -114,9 +114,12 @@
   au1500_iflist[NUM_INTERFACES] = {
 		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
 		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
+	},
+  au1100_iflist[NUM_INTERFACES] = {
+		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
+		{NULL, NULL}
 	};
 
-
 static char version[] __devinitdata =
     "au1000eth.c:1.0 ppopov@mvista.com\n";
 
@@ -168,6 +171,11 @@
 	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
 	mdio_write(dev, phy_addr, MII_CONTROL, data);
 
+	/* Enable TX LED instead of FDX */
+	data = mdio_read(dev, phy_addr, MII_INT);
+	data &= ~MII_FDX_LED;
+	mdio_write(dev, phy_addr, MII_INT, data);
+
 	if (au1000_debug > 4) dump_mii(dev, phy_addr);
 	return 0;
 }
@@ -241,6 +249,8 @@
 	/* restart auto-negotiation */
 	mdio_write(dev, phy_addr, 0, 0x3200);
 
+	mdelay(1);
+
 	/* set up LEDs to correct display */
 	mdio_write(dev, phy_addr, 17, 0xffc0);
 
@@ -359,6 +369,7 @@
 	{"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 },
+	{"Broadcom BCM5221 10/100 BaseT PHY",  0x0040, 0x61e4, &bcm_5201_ops },
 	{0,},
 };
 
@@ -629,14 +640,20 @@
 		} else if ( (prid & 0xffff0000) == 0x01030000 ) {
 			base_addr = au1500_iflist[i].port;
 			irq = au1500_iflist[i].irq;
+		} else if ( (prid & 0xffff0000) == 0x02030000 ) {
+			base_addr = au1100_iflist[i].port;
+			irq = au1100_iflist[i].irq;
 		} else {
 			printk(KERN_ERR "au1000 eth: unknown Processor ID\n");
 			return -ENODEV;
 		}
+		// check for valid entries, au1100 only has one entry
+		if (base_addr && irq) {
 		if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
 			return -ENODEV;
 		}
 	}
+	}
 	return 0;
 }
 
diff -urN linux-2.4.20-pre6/drivers/net/au1000_eth.h linux-2.4.20-pre7/drivers/net/au1000_eth.h
--- linux-2.4.20-pre6/drivers/net/au1000_eth.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/net/au1000_eth.h	Thu Sep 12 20:01:44 2002
@@ -33,7 +33,7 @@
 #define ETH_TX_TIMEOUT HZ/4
 #define MAC_MIN_PKT_SIZE 64
 
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500)
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
 #define PHY_ADDRESS              0
 #define PHY_CONTROL_DEFAULT 0x3000
 #define PHY_CONTROL_REG_ADDR     0
@@ -57,6 +57,7 @@
 #define MII_LSI_CONFIG 0x0011
 #define MII_LSI_STAT   0x0012
 #define MII_AUX_CNTRL  0x0018
+#define MII_INT        0x001A
 
 /* mii registers specific to AMD 79C901 */
 #define	MII_STATUS_SUMMARY = 0x0018
@@ -122,14 +123,15 @@
 
 /* lsi status register */
 
-#define MII_LSI_STAT_FDX	0x0008
-#define MII_LSI_STAT_SPD	0x0010
+#define MII_LSI_STAT_FDX	0x0040
+#define MII_LSI_STAT_SPD	0x0080
 
 /* Auxilliary Control/Status Register */
 #define MII_AUX_FDX      0x0001
 #define MII_AUX_100      0x0002
 #define MII_AUX_F100     0x0004
 #define MII_AUX_ANEG     0x0008
+#define MII_FDX_LED	 0x8000
 
 typedef struct mii_phy {
 	struct mii_phy * next;
diff -urN linux-2.4.20-pre6/drivers/net/declance.c linux-2.4.20-pre7/drivers/net/declance.c
--- linux-2.4.20-pre6/drivers/net/declance.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/net/declance.c	Thu Sep 12 20:01:44 2002
@@ -43,8 +43,10 @@
  */
 
 #include <linux/config.h>
+#include <linux/crc32.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/if_ether.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -60,7 +62,7 @@
 #include <asm/dec/kn01.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
-#include <asm/wbflush.h>
+#include <asm/system.h>
 
 static char version[] __devinitdata =
 "declance.c: v0.009 by Linux MIPS DECstation task force\n";
@@ -81,9 +83,6 @@
 unsigned long dmaptr;
 #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
@@ -290,7 +289,7 @@
 static inline void writereg(volatile unsigned short *regptr, short value)
 {
 	*regptr = value;
-	wbflush();
+	iob();
 }
 
 /* Load the CSR registers */
@@ -370,7 +369,7 @@
 		}
 	}
 
-	wbflush();
+	iob();
 }
 
 void cp_from_buf(const int type, void *to, const void *from, int len)
@@ -498,7 +497,7 @@
 		if (i < 3 && ZERO)
 			printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]);
 	}
-	wbflush();
+	iob();
 }
 
 static int init_restart_lance(struct lance_private *lp)
@@ -795,7 +794,7 @@
 			return -EAGAIN;
 		}
 		/* Enable I/O ASIC LANCE DMA.  */
-		wbflush();
+		fast_wmb();
 		ioasic_write(SSR, ioasic_read(SSR) | LANCE_DMA_EN);
 	}
 
@@ -824,7 +823,7 @@
 	if (lp->dma_irq >= 0) {
 		/* Disable I/O ASIC LANCE DMA.  */
 		ioasic_write(SSR, ioasic_read(SSR) & ~LANCE_DMA_EN);
-		wbflush();
+		fast_iob();
 		free_irq(lp->dma_irq, dev);
 	}
 	free_irq(dev->irq, dev);
@@ -921,7 +920,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) {
@@ -946,19 +945,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(ETH_ALEN, addrs);
 		crc = crc >> 26;
 		mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf);
 	}
diff -urN linux-2.4.20-pre6/drivers/net/meth.c linux-2.4.20-pre7/drivers/net/meth.c
--- linux-2.4.20-pre6/drivers/net/meth.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/net/meth.c	Thu Sep 12 20:01:44 2002
@@ -0,0 +1,863 @@
+/*
+ * meth.c -- O2 Builtin 10/100 Ethernet driver
+ *
+ * Copyright (C) 2001 Ilya Volynets
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the 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/init.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+#include <linux/pci.h>
+
+#include <linux/in.h>
+#include <linux/netdevice.h>   /* struct device, and other headers */
+#include <linux/etherdevice.h> /* eth_type_trans */
+#include <linux/ip.h>          /* struct iphdr */
+#include <linux/tcp.h>         /* struct tcphdr */
+#include <linux/skbuff.h>
+#include <linux/mii.h> /*MII definitions */
+
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+#include "meth.h"
+
+#include <linux/in6.h>
+#include <asm/checksum.h>
+
+#ifndef MFE_DEBUG
+#define MFE_DEBUG 0
+#endif
+
+#if MFE_DEBUG>=1
+#define DPRINTK(str,args...) printk (KERN_DEBUG "meth(%ld): %s: " str, jiffies, __FUNCTION__ , ## args)
+#define MFE_RX_DEBUG 2
+#else
+#define DPRINTK(str,args...)
+#define MFE_RX_DEBUG 0
+#endif
+
+
+static const char *version="meth.c: Ilya Volynets (ilya@theIlya.com)";
+static const char *meth_str="SGI O2 Fast Ethernet";
+MODULE_AUTHOR("Ilya Volynets");
+MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
+
+/* This is a load-time options */
+/*static int eth = 0;
+MODULE_PARM(eth, "i");*/
+
+#define HAVE_TX_TIMEOUT
+/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
+#define TX_TIMEOUT (400*HZ/1000)
+
+#ifdef HAVE_TX_TIMEOUT
+static int timeout = TX_TIMEOUT;
+MODULE_PARM(timeout, "i");
+#endif
+
+int meth_eth;
+
+
+/*
+ * This structure is private to each device. It is used to pass
+ * packets in and out, so there is place for a packet
+ */
+
+typedef struct meth_private {
+    struct net_device_stats stats;
+	volatile struct meth_regs *regs;
+	u64 mode; /* in-memory copy of MAC control register */
+	int  phy_addr; /* address of phy, used by mdio_* functions, initialized in mdio_probe*/
+	tx_packet *tx_ring;
+	dma_addr_t tx_ring_dma;
+	int free_space;
+	struct sk_buff *tx_skbs[TX_RING_ENTRIES];
+	dma_addr_t      tx_skb_dmas[TX_RING_ENTRIES];
+	int tx_read,tx_write;
+	int tx_count;
+
+	rx_packet *rx_ring[RX_RING_ENTRIES];
+	dma_addr_t rx_ring_dmas[RX_RING_ENTRIES];
+	int rx_write;
+
+    spinlock_t meth_lock;
+} meth_private;
+
+extern struct net_device meth_devs[];
+void meth_tx_timeout (struct net_device *dev);
+void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
+        
+/* global, initialized in ip32-setup.c */
+char o2meth_eaddr[8]={0,0,0,0,0,0,0,0};
+
+static inline void load_eaddr(struct net_device *dev,
+			      volatile struct meth_regs *regs)
+{
+	int i;
+	DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+		(int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF,
+		(int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF);
+	//memcpy(dev->dev_addr,o2meth_eaddr+2,6);
+	for (i=0; i<6; i++)
+		dev->dev_addr[i]=o2meth_eaddr[i];
+	regs->mac_addr= //dev->dev_addr[0]|(dev->dev_addr[1]<<8)|
+					//dev->dev_addr[2]<<16|(dev->dev_addr[3]<<24)|
+					//dev->dev_addr[4]<<32|(dev->dev_addr[5]<<40);
+	(*(u64*)o2meth_eaddr)>>16;
+	DPRINTK("MAC, finally is %0lx\n",regs->mac_addr);
+}
+
+/*
+ *Waits for BUSY status of mdio bus to clear
+ */
+#define WAIT_FOR_PHY(___regs, ___rval)			\
+	while((___rval=___regs->phy_data)&MDIO_BUSY){	\
+		udelay(25);								\
+	}
+/*read phy register, return value read */
+static int mdio_read(meth_private *priv,int phyreg)
+{
+	volatile meth_regs* regs=priv->regs;
+	volatile u32 rval;
+	WAIT_FOR_PHY(regs,rval)
+	regs->phy_registers=(priv->phy_addr<<5)|(phyreg&0x1f);
+	udelay(25);
+	regs->phy_trans_go=1;
+	udelay(25);
+	WAIT_FOR_PHY(regs,rval)
+	return rval&MDIO_DATA_MASK;
+}
+
+/*write phy register */
+static void mdio_write(meth_private* priv,int pfyreg,int val)
+{
+	volatile meth_regs* regs=priv->regs;
+	int rval;
+///	DPRINTK("Trying to write value %i to reguster %i\n",val, pfyreg);
+	spin_lock_irq(&priv->meth_lock);
+	WAIT_FOR_PHY(regs,rval)
+	regs->phy_registers=(priv->phy_addr<<5)|(pfyreg&0x1f);
+	regs->phy_data=val;
+	udelay(25);
+	WAIT_FOR_PHY(regs,rval)
+	spin_unlock_irq(&priv->meth_lock);
+}
+
+/* Modify phy register using given mask and value */
+static void mdio_update(meth_private* priv,int phyreg, int val, int mask)
+{
+	int rval;
+	DPRINTK("RMW value %i to PHY register %i with mask %i\n",val,phyreg,mask);
+	rval=mdio_read(priv,phyreg);
+	rval=(rval&~mask)|(val&mask);
+	mdio_write(priv,phyreg,rval);
+}
+
+/* handle errata data on MDIO bus */
+//static void mdio_errata(meth_private *priv)
+//{
+	/* Hmmm... what the hell is phyerrata? does it come from sys init parameters in IRIX */
+//}
+static int mdio_probe(meth_private *priv)
+{
+	int i, p2, p3;
+	DPRINTK("Detecting PHY kind\n");
+	/* check if phy is detected already */
+	if(priv->phy_addr>=0&&priv->phy_addr<32)
+		return 0;
+	spin_lock_irq(&priv->meth_lock);
+	for (i=0;i<32;++i){
+		priv->phy_addr=(char)i;
+		p2=mdio_read(priv,2);
+#ifdef MFE_DEBUG
+		p3=mdio_read(priv,3);
+		switch ((p2<<12)|(p3>>4)){
+			case PHY_QS6612X:
+				DPRINTK("PHY is QS6612X\n");
+				break;
+			case PHY_ICS1889:
+				DPRINTK("PHY is ICS1889\n");
+				break;
+			case PHY_ICS1890:
+				DPRINTK("PHY is ICS1890\n");
+				break;
+			case PHY_DP83840:
+				DPRINTK("PHY is DP83840\n");
+				break;
+		}
+#endif
+		if(p2!=0xffff&&p2!=0x0000){
+			DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4));
+			break;
+		}
+	}
+	spin_unlock_irq(&priv->meth_lock);
+	if(priv->phy_addr<32) {
+		return 0;
+	}
+	DPRINTK("Oopsie! PHY is not known!\n");
+	priv->phy_addr=-1;
+	return -ENODEV;
+}
+
+static void meth_check_link(struct net_device *dev)
+{
+	struct meth_private *priv = (struct meth_private *) dev->priv;
+	int mii_partner = mdio_read(priv, 5);
+	int mii_advertising = mdio_read(priv, 4);
+	int negotiated = mii_advertising & mii_partner;
+	int duplex, speed;
+
+	if (mii_partner == 0xffff)
+		return;
+
+	duplex = ((negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040)?METH_PHY_FDX:0;
+	speed = (negotiated & 0x0380)?METH_100MBIT:0;
+
+	if ((priv->mode & METH_PHY_FDX) ^ duplex)
+	{
+		DPRINTK("Setting %s-duplex\n", duplex ? "full" : "half");
+		if (duplex)
+			priv->mode |= METH_PHY_FDX;
+		else
+			priv->mode &= ~METH_PHY_FDX;
+		priv->regs->mac_ctrl = priv->mode;
+	}
+
+	if ((priv->mode & METH_100MBIT) ^ speed)
+	{
+		DPRINTK("Setting %dMbs mode\n", speed ? 100 : 10);
+		if (duplex)
+			priv->mode |= METH_100MBIT;
+		else
+			priv->mode &= ~METH_100MBIT;
+		priv->regs->mac_ctrl = priv->mode;
+	}
+}
+
+
+static int meth_init_tx_ring(meth_private *priv)
+{
+	/* Init TX ring */
+	DPRINTK("Initializing TX ring\n");
+	priv->tx_ring = (tx_packet *) pci_alloc_consistent(NULL,TX_RING_BUFFER_SIZE,&(priv->tx_ring_dma));
+	if(!priv->tx_ring)
+		return -ENOMEM;
+	memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE);
+	priv->tx_count = priv->tx_read = priv->tx_write = 0;
+	priv->regs->tx_ring_base = priv->tx_ring_dma;
+	priv->free_space = TX_RING_ENTRIES;
+	/* Now init skb save area */
+	memset(priv->tx_skbs,0,sizeof(priv->tx_skbs));
+	memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas));
+	DPRINTK("Done with TX ring init\n");
+	return 0;
+}
+
+static int meth_init_rx_ring(meth_private *priv)
+{
+	int i;
+	DPRINTK("Initializing RX ring\n");
+	for(i=0;i<RX_RING_ENTRIES;i++){
+		DPRINTK("\t1:\t%i\t",i);
+		/*if(!(priv->rx_ring[i]=get_free_page(GFP_KERNEL)))
+			return -ENOMEM;
+		DPRINTK("\t2:\t%i\n",i);*/
+		priv->rx_ring[i]=(rx_packet*)pci_alloc_consistent(NULL,METH_RX_BUFF_SIZE,&(priv->rx_ring_dmas[i]));
+		/* I'll need to re-sync it after each RX */
+		DPRINTK("\t%p\n",priv->rx_ring[i]);
+		priv->regs->rx_fifo=priv->rx_ring_dmas[i];
+	}
+	priv->rx_write = 0;
+	DPRINTK("Done with RX ring\n");
+	return 0;
+}
+static void meth_free_tx_ring(meth_private *priv)
+{
+	int i;
+
+	/* Remove any pending skb */
+	for (i = 0; i < TX_RING_ENTRIES; i++) {
+	  if (priv->tx_skbs[i])
+		dev_kfree_skb(priv->tx_skbs[i]);
+		priv->tx_skbs[i] = NULL;
+	}
+	pci_free_consistent(NULL,
+			    TX_RING_BUFFER_SIZE,
+			    priv->tx_ring,
+			    priv->tx_ring_dma);
+}
+static void meth_free_rx_ring(meth_private *priv)
+{
+	int i;
+
+	for(i=0;i<RX_RING_ENTRIES;i++)
+		pci_free_consistent(NULL,
+				    METH_RX_BUFF_SIZE,
+				    priv->rx_ring[i],
+				    priv->rx_ring_dmas[i]);
+}
+
+int meth_reset(struct net_device *dev)
+{
+	struct meth_private *priv = (struct meth_private *) dev->priv;
+
+	/* Reset card */
+	priv->regs->mac_ctrl = SGI_MAC_RESET;
+	priv->regs->mac_ctrl = 0;
+	udelay(25);
+	DPRINTK("MAC control after reset: %016lx\n", priv->regs->mac_ctrl);
+
+	/* Load ethernet address */
+	load_eaddr(dev, priv->regs);
+	/* Should load some "errata", but later */
+	
+	/* Check for device */
+	if(mdio_probe(priv) < 0) {
+		DPRINTK("Unable to find PHY\n");
+		return -ENODEV;
+	}
+
+	/* Initial mode -- 10|Half-duplex|Accept normal packets */
+	priv->mode=METH_ACCEPT_MCAST|METH_DEFAULT_IPG;
+	if(dev->flags | IFF_PROMISC)
+		priv->mode |= METH_PROMISC;
+	priv->regs->mac_ctrl = priv->mode;
+
+	/* Autonegociate speed and duplex mode */
+	meth_check_link(dev);
+
+	/* Now set dma control, but don't enable DMA, yet */
+	priv->regs->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) |
+		              (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
+
+	return(0);
+}
+
+/*============End Helper Routines=====================*/
+
+/*
+ * Open and close
+ */
+
+int meth_open(struct net_device *dev)
+{
+	meth_private *priv=dev->priv;
+	volatile meth_regs *regs=priv->regs;
+
+	MOD_INC_USE_COUNT;
+
+	/* Start DMA */
+	regs->dma_ctrl|=
+	        METH_DMA_TX_EN|/*METH_DMA_TX_INT_EN|*/
+		METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
+
+	if(request_irq(dev->irq,meth_interrupt,SA_SHIRQ,meth_str,dev)){
+		printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq);
+		return -EAGAIN;
+	}
+	netif_start_queue(dev);
+	DPRINTK("Opened... DMA control=0x%08lx\n", regs->dma_ctrl);
+	return 0;
+}
+
+int meth_release(struct net_device *dev)
+{
+    netif_stop_queue(dev); /* can't transmit any more */
+	/* shut down dma */
+	((meth_private*)(dev->priv))->regs->dma_ctrl&=
+		~(METH_DMA_TX_EN|METH_DMA_TX_INT_EN|
+		METH_DMA_RX_EN|METH_DMA_RX_INT_EN);
+	free_irq(dev->irq, dev);
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+/*
+ * Configuration changes (passed on by ifconfig)
+ */
+int meth_config(struct net_device *dev, struct ifmap *map)
+{
+    if (dev->flags & IFF_UP) /* can't act on a running interface */
+        return -EBUSY;
+
+    /* Don't allow changing the I/O address */
+    if (map->base_addr != dev->base_addr) {
+        printk(KERN_WARNING "meth: Can't change I/O address\n");
+        return -EOPNOTSUPP;
+    }
+
+    /* Allow changing the IRQ */
+    if (map->irq != dev->irq) {
+        printk(KERN_WARNING "meth: Can't change IRQ\n");
+        return -EOPNOTSUPP;
+    }
+	DPRINTK("Configured\n");
+
+    /* ignore other fields */
+    return 0;
+}
+
+/*
+ * Receive a packet: retrieve, encapsulate and pass over to upper levels
+ */
+void meth_rx(struct net_device* dev)
+{
+    struct sk_buff *skb;
+    struct meth_private *priv = (struct meth_private *) dev->priv;
+	rx_packet *rxb;
+	DPRINTK("RX...\n");
+	// TEMP	while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){
+	while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){
+	        int len=rxb->status.parsed.rx_len - 4; /* omit CRC */
+		DPRINTK("(%i)\n",priv->rx_write);
+		/* length sanity check */
+		if(len < 60 || len > 1518) {
+		  printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x.\n",
+			 dev->name, priv->rx_write, rxb->status.raw);
+		  priv->stats.rx_errors++;
+		  priv->stats.rx_length_errors++;
+		}
+		if(!(rxb->status.raw&METH_RX_STATUS_ERRORS)){
+			skb=alloc_skb(len+2,GFP_ATOMIC);/* Should be atomic -- we are in interrupt */
+			if(!skb){
+				/* Ouch! No memory! Drop packet on the floor */
+				DPRINTK("!!!>>>Ouch! Not enough Memory for RX buffer!\n");
+				priv->stats.rx_dropped++;
+			} else {
+				skb_reserve(skb, 2); /* align IP on 16B boundary */  
+    			memcpy(skb_put(skb, len), rxb->buf, len);
+			    /* Write metadata, and then pass to the receive level */
+			    skb->dev = dev;
+			    skb->protocol = eth_type_trans(skb, dev);
+				//skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
+			   
+				DPRINTK("passing packet\n");
+				DPRINTK("len = %d rxb->status = %x\n",
+					len, rxb->status.raw);
+				netif_rx(skb);
+				dev->last_rx = jiffies;
+				priv->stats.rx_packets++;
+				priv->stats.rx_bytes+=len;
+				DPRINTK("There we go... Whew...\n");
+			}
+		}
+		priv->regs->rx_fifo=priv->rx_ring_dmas[priv->rx_write];
+		rxb->status.raw=0;		
+		priv->rx_write=(priv->rx_write+1)&(RX_RING_ENTRIES-1);
+	}
+}
+
+static int meth_tx_full(struct net_device *dev)
+{
+	struct meth_private *priv = (struct meth_private *) dev->priv;
+
+	return(priv->tx_count >= TX_RING_ENTRIES-1);
+}
+
+void meth_tx_cleanup(struct net_device* dev, int rptr)
+{
+	meth_private *priv=dev->priv;
+	tx_packet* status;
+	struct sk_buff *skb;
+
+	spin_lock(&priv->meth_lock);
+
+	/* Stop DMA */
+	priv->regs->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
+
+	while(priv->tx_read != rptr){
+		skb = priv->tx_skbs[priv->tx_read];
+		status = &priv->tx_ring[priv->tx_read];
+		if(!status->header.res.sent)
+			break;
+		if(status->header.raw & METH_TX_STATUS_DONE) {
+			priv->stats.tx_packets++;
+			priv->stats.tx_bytes += skb->len;
+		}
+		dev_kfree_skb_irq(skb);
+		priv->tx_skbs[priv->tx_read] = NULL;
+		status->header.raw = 0;
+		priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1);
+		priv->tx_count --;
+	}
+
+	/* wake up queue if it was stopped */
+	if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) {
+		netif_wake_queue(dev);
+	}
+
+	spin_unlock(priv->meth_lock);
+}
+
+/*
+ * The typical interrupt entry point
+ */
+void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs)
+{
+	struct meth_private *priv;
+	union {
+		u32	reg; /*Whole status register */
+		struct {
+			u32			:	2,
+				rx_seq	:	5,
+				tx_read	:	9,
+				
+				rx_read	:	8,
+				int_mask:	8;
+		} parsed;
+	} status;
+	/*
+	 * As usual, check the "device" pointer for shared handlers.
+	 * Then assign "struct device *dev"
+	 */
+	struct net_device *dev = (struct net_device *)dev_id;
+	/* ... and check with hw if it's really ours */
+
+	if (!dev /*paranoid*/ ) return;
+
+	/* Lock the device */
+	priv = (struct meth_private *) dev->priv;
+
+	status.reg = priv->regs->int_flags;
+    
+	DPRINTK("Interrupt, status %08x...\n",status.reg);
+	if (status.parsed.int_mask & METH_INT_RX_THRESHOLD) {
+		/* send it to meth_rx for handling */
+		meth_rx(dev);
+	}
+
+	if (status.parsed.int_mask & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) {
+		/* a transmission is over: free the skb */
+		meth_tx_cleanup(dev, status.parsed.tx_read);
+	}
+	/* check for errors too... */
+	if (status.parsed.int_mask & (METH_INT_TX_LINK_FAIL))
+		printk(KERN_WARNING "meth: link failure\n");
+	if (status.parsed.int_mask & (METH_INT_MEM_ERROR))
+		printk(KERN_WARNING "meth: memory error\n");
+	if (status.parsed.int_mask & (METH_INT_TX_ABORT))
+		printk(KERN_WARNING "meth: aborted\n");
+	DPRINTK("Interrupt handling done...\n");
+	
+	priv->regs->int_flags=status.reg&0xff; /* clear interrupts */
+}
+
+/*
+ * Transmits packets that fit into TX descriptor (are <=120B)
+ */
+static void meth_tx_short_prepare(meth_private* priv, struct sk_buff* skb)
+{
+	tx_packet *desc=&priv->tx_ring[priv->tx_write];
+	int len = (skb->len<ETH_ZLEN)?ETH_ZLEN:skb->len;
+
+	DPRINTK("preparing short packet\n");
+	/* maybe I should set whole thing to 0 first... */
+	memcpy(desc->data.dt+(120-len),skb->data,skb->len);
+	if(skb->len < len)
+		memset(desc->data.dt+120-len+skb->len,0,len-skb->len);
+	desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16);
+	DPRINTK("desc=%016lx\n",desc->header.raw);
+}
+#define TX_CATBUF1 BIT(25)
+static void meth_tx_1page_prepare(meth_private* priv, struct sk_buff* skb)
+{
+	tx_packet *desc=&priv->tx_ring[priv->tx_write];
+	void *buffer_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL));
+	int unaligned_len = (int)((u64)buffer_data - (u64)skb->data);
+	int buffer_len = skb->len - unaligned_len;
+	dma_addr_t catbuf;
+
+	DPRINTK("preparing 1 page...\n");
+	DPRINTK("length=%d data=%p\n", skb->len, skb->data);
+	DPRINTK("unaligned_len=%d\n", unaligned_len);
+	DPRINTK("buffer_data=%p buffer_len=%d\n",
+	       buffer_data,
+	       buffer_len);
+
+	desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1);
+
+	/* unaligned part */
+	if(unaligned_len){
+		memcpy(desc->data.dt+(120-unaligned_len),
+		       skb->data, unaligned_len);
+		desc->header.raw |= (128-unaligned_len) << 16;
+	}
+
+	/* first page */
+	catbuf = pci_map_single(NULL,
+				buffer_data,
+				buffer_len,
+				PCI_DMA_TODEVICE);
+	DPRINTK("catbuf=%x\n", catbuf);
+	desc->data.cat_buf[0].form.start_addr = catbuf >> 3;
+	desc->data.cat_buf[0].form.len = buffer_len-1;
+	DPRINTK("desc=%016lx\n",desc->header.raw);
+	DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw);
+}
+#define TX_CATBUF2 BIT(26)
+static void meth_tx_2page_prepare(meth_private* priv, struct sk_buff* skb)
+{
+	tx_packet *desc=&priv->tx_ring[priv->tx_write];
+	void *buffer1_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL));
+	void *buffer2_data = (void *)PAGE_ALIGN((u64)skb->data);
+	int unaligned_len = (int)((u64)buffer1_data - (u64)skb->data);
+	int buffer1_len = (int)((u64)buffer2_data - (u64)buffer1_data);
+	int buffer2_len = skb->len - buffer1_len - unaligned_len;
+	dma_addr_t catbuf1, catbuf2;
+
+	DPRINTK("preparing 2 pages... \n");
+	DPRINTK("length=%d data=%p\n", skb->len, skb->data);
+	DPRINTK("unaligned_len=%d\n", unaligned_len);
+	DPRINTK("buffer1_data=%p buffer1_len=%d\n",
+	       buffer1_data,
+	       buffer1_len);
+	DPRINTK("buffer2_data=%p buffer2_len=%d\n",
+	       buffer2_data,
+	       buffer2_len);
+
+	desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1);
+	/* unaligned part */
+	if(unaligned_len){
+		memcpy(desc->data.dt+(120-unaligned_len),
+		       skb->data, unaligned_len);
+		desc->header.raw |= (128-unaligned_len) << 16;
+	}
+
+	/* first page */
+	catbuf1 = pci_map_single(NULL,
+				 buffer1_data,
+				 buffer1_len,
+				 PCI_DMA_TODEVICE);
+	DPRINTK("catbuf1=%x\n", catbuf1);
+	desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3;
+	desc->data.cat_buf[0].form.len = buffer1_len-1;
+	/* second page */
+	catbuf2 = pci_map_single(NULL,
+				 buffer2_data,
+				 buffer2_len,
+				 PCI_DMA_TODEVICE);
+	DPRINTK("catbuf2=%x\n", catbuf2);
+	desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3;
+	desc->data.cat_buf[1].form.len = buffer2_len-1;
+	DPRINTK("desc=%016lx\n",desc->header.raw);
+	DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw);
+	DPRINTK("cat_buf[1].raw=%016lx\n",desc->data.cat_buf[1].raw);
+}
+
+
+void meth_add_to_tx_ring(meth_private *priv, struct sk_buff* skb)
+{
+	DPRINTK("Transmitting data...\n");
+	if(skb->len <= 120) {
+		/* Whole packet fits into descriptor */
+		meth_tx_short_prepare(priv,skb);
+	} else if(PAGE_ALIGN((u64)skb->data) !=
+		  PAGE_ALIGN((u64)skb->data+skb->len-1)) {
+		/* Packet crosses page boundary */
+		meth_tx_2page_prepare(priv,skb);
+	} else {
+		/* Packet is in one page */
+		meth_tx_1page_prepare(priv,skb);
+	}
+
+	/* Remember the skb, so we can free it at interrupt time */
+	priv->tx_skbs[priv->tx_write] = skb;
+	priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1);
+	priv->regs->tx_info.wptr = priv->tx_write;
+	priv->tx_count ++;
+	/* Enable DMA transfer */
+	priv->regs->dma_ctrl |= METH_DMA_TX_INT_EN;
+}
+
+/*
+ * Transmit a packet (called by the kernel)
+ */
+int meth_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct meth_private *priv = (struct meth_private *) dev->priv;
+
+	spin_lock_irq(&priv->meth_lock);
+
+	meth_add_to_tx_ring(priv, skb);
+	dev->trans_start = jiffies; /* save the timestamp */
+
+	/* If TX ring is full, tell the upper layer to stop sending packets */
+	if (meth_tx_full(dev)) {
+	        DPRINTK("TX full: stopping\n");
+		netif_stop_queue(dev);
+	}
+
+	spin_unlock_irq(&priv->meth_lock);
+
+	return 0;
+}
+
+/*
+ * Deal with a transmit timeout.
+ */
+
+void meth_tx_timeout (struct net_device *dev)
+{
+	struct meth_private *priv = (struct meth_private *) dev->priv;
+	
+	printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
+
+	/* Protect against concurrent rx interrupts */
+	spin_lock_irq(&priv->meth_lock);
+
+	/* Try to reset the adaptor. */
+	meth_reset(dev);
+
+	priv->stats.tx_errors++;
+
+	/* Clear all rings */
+	meth_free_tx_ring(priv);
+	meth_free_rx_ring(priv);
+	meth_init_tx_ring(priv);
+	meth_init_rx_ring(priv);
+
+	/* Restart dma */
+	priv->regs->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
+
+	/* Enable interrupt */
+	spin_unlock_irq(&priv->meth_lock);
+
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+
+	return;
+}
+
+/*
+ * Ioctl commands 
+ */
+int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ 
+    DPRINTK("ioctl\n");
+    return 0;
+}
+
+/*
+ * Return statistics to the caller
+ */
+struct net_device_stats *meth_stats(struct net_device *dev)
+{
+    struct meth_private *priv = (struct meth_private *) dev->priv;
+    return &priv->stats;
+}
+
+/*
+ * The init function (sometimes called probe).
+ * It is invoked by register_netdev()
+ */
+int meth_init(struct net_device *dev)
+{
+	meth_private *priv;
+	int ret;
+	/* 
+	 * Then, assign other fields in dev, using ether_setup() and some
+	 * hand assignments
+	 */
+	ether_setup(dev); /* assign some of the fields */
+
+	dev->open            = meth_open;
+	dev->stop            = meth_release;
+	dev->set_config      = meth_config;
+	dev->hard_start_xmit = meth_tx;
+	dev->do_ioctl        = meth_ioctl;
+	dev->get_stats       = meth_stats;
+#ifdef HAVE_TX_TIMEOUT
+	dev->tx_timeout      = meth_tx_timeout;
+	dev->watchdog_timeo  = timeout;
+#endif
+	dev->irq		 = MACE_ETHERNET_IRQ;
+	SET_MODULE_OWNER(dev);
+
+	/*
+	 * Then, allocate the priv field. This encloses the statistics
+	 * and a few private fields.
+	 */
+	priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL);
+	if (priv == NULL)
+		return -ENOMEM;
+	dev->priv=priv;
+	memset(priv, 0, sizeof(struct meth_private));
+	spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock);
+	/*
+	 * Make the usual checks: check_region(), probe irq, ...  -ENODEV
+	 * should be returned if no device found.  No resource should be
+	 * grabbed: this is done on open(). 
+	 */
+	priv->regs=(meth_regs*)SGI_MFE;
+	dev->base_addr=SGI_MFE;
+	priv->phy_addr = -1; /* No phy is known yet... */
+
+	/* Initialize the hardware */
+	if((ret=meth_reset(dev)) < 0)
+	        return ret;
+
+	/* Allocate the ring buffers */
+	if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){
+		meth_free_tx_ring(priv);
+		meth_free_rx_ring(priv);
+		return ret;
+	}
+
+	printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29);
+
+    return 0;
+}
+
+/*
+ * The devices
+ */
+
+struct net_device meth_devs[1] = {
+    { init: meth_init, }  /* init, nothing more */
+};
+
+/*
+ * Finally, the module stuff
+ */
+
+int meth_init_module(void)
+{
+	int result, device_present = 0;
+
+	strcpy(meth_devs[0].name, "eth%d");
+
+	if ( (result = register_netdev(meth_devs)) )
+		printk("meth: error %i registering device \"%s\"\n",
+		       result, meth_devs->name);
+	else device_present++;
+#ifndef METH_DEBUG
+	EXPORT_NO_SYMBOLS;
+#endif
+	
+	return device_present ? 0 : -ENODEV;
+}
+
+void meth_cleanup(void)
+{
+    kfree(meth_devs->priv);
+    unregister_netdev(meth_devs);
+    return;
+}
+
+module_init(meth_init_module);
+module_exit(meth_cleanup);
diff -urN linux-2.4.20-pre6/drivers/net/meth.h linux-2.4.20-pre7/drivers/net/meth.h
--- linux-2.4.20-pre6/drivers/net/meth.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/net/meth.h	Thu Sep 12 20:01:44 2002
@@ -0,0 +1,273 @@
+
+/*
+ * snull.h -- definitions for the network module
+ *
+ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
+ * Copyright (C) 2001 O'Reilly & Associates
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files.  The citation
+ * should list that the code comes from the book "Linux Device
+ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
+ * by O'Reilly & Associates.   No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ */
+
+/* version dependencies have been confined to a separate file */
+
+#define SGI_MFE		(MACE_BASE+MACE_ENET)
+/*		(0xBF280000)*/
+
+/* Tunable parameters */
+#define TX_RING_ENTRIES 64	/* 64-512?*/
+
+#define RX_RING_ENTRIES 16 /* Do not change */
+/* Internal constants */
+#define TX_RING_BUFFER_SIZE	(TX_RING_ENTRIES*sizeof(tx_packet))
+#define RX_BUFFER_SIZE 1546 /* ethenet packet size */
+#define METH_RX_BUFF_SIZE 4096
+#define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */
+#define RX_BUCKET_SIZE 256
+
+
+
+/* For more detailed explanations of what each field menas,
+   see Nick's great comments to #defines below (or docs, if
+   you are lucky enough toget hold of them :)*/
+
+/* tx status vector is written over tx command header upon
+   dma completion. */
+
+typedef struct tx_status_vector {
+	u64		sent:1; /* always set to 1...*/
+	u64		pad0:34;/* always set to 0 */
+	u64		flags:9;			/*I'm too lazy to specify each one separately at the moment*/
+	u64		col_retry_cnt:4;	/*collision retry count*/
+	u64		len:16;				/*Transmit length in bytes*/
+} tx_status_vector;
+
+/*
+ * Each packet is 128 bytes long.
+ * It consists of header, 0-3 concatination
+ * buffer pointers and up to 120 data bytes.
+ */
+typedef struct tx_packet_hdr {
+	u64		pad1:36; /*should be filled with 0 */
+	u64		cat_ptr3_valid:1,	/*Concatination pointer valid flags*/
+			cat_ptr2_valid:1,
+			cat_ptr1_valid:1;
+	u64		tx_int_flag:1;		/*Generate TX intrrupt when packet has been sent*/
+	u64		term_dma_flag:1;	/*Terminate transmit DMA on transmit abort conditions*/
+	u64		data_offset:7;		/*Starting byte offset in ring data block*/
+	u64		data_len:16;		/*Length of valid data in bytes-1*/
+} tx_packet_hdr;
+typedef union tx_cat_ptr {
+	struct {
+		u64		pad2:16; /* should be 0 */
+		u64		len:16;				/*length of buffer data - 1*/
+		u64		start_addr:29;		/*Physical starting address*/
+		u64		pad1:3; /* should be zero */
+	} form;
+	u64 raw;
+} tx_cat_ptr;
+
+typedef struct tx_packet {
+	union {
+		tx_packet_hdr header;
+		tx_status_vector res;
+		u64 raw;
+	}header;
+	union {
+		tx_cat_ptr cat_buf[3];
+		char dt[120];
+	} data;
+} tx_packet;
+
+typedef union rx_status_vector {
+	struct {
+		u64		pad1:1;/*fill it with ones*/
+		u64		pad2:15;/*fill with 0*/
+		u64		ip_chk_sum:16;
+		u64		seq_num:5;
+		u64		mac_addr_match:1;
+		u64		mcast_addr_match:1;
+		u64		carrier_event_seen:1;
+		u64		bad_packet:1;
+		u64		long_event_seen:1;
+		u64		invalid_preamble:1;
+		u64		broadcast:1;
+		u64		multicast:1;
+		u64		crc_error:1;
+		u64		huh:1;/*???*/
+		u64		rx_code_violation:1;
+		u64		rx_len:16;
+	} parsed;
+	u64 raw;
+} rx_status_vector;
+
+typedef struct rx_packet {
+	rx_status_vector status;
+        u64 pad[3]; /* For whatever reason, there needs to be 4 double-word offset */
+        u16 pad2;
+	char buf[METH_RX_BUFF_SIZE-sizeof(rx_status_vector)-3*sizeof(u64)-sizeof(u16)];/* data */
+} rx_packet;
+
+typedef struct meth_regs {
+	u64		mac_ctrl;		/*0x00,rw,31:0*/
+	u64		int_flags;		/*0x08,rw,30:0*/
+	u64		dma_ctrl;		/*0x10,rw,15:0*/
+	u64		timer;			/*0x18,rw,5:0*/
+	u64		int_tx;			/*0x20,wo,0:0*/
+	u64		int_rx;			/*0x28,wo,9:4*/
+	struct {
+		u32 tx_info_pad;
+		u32 rptr:16,wptr:16;
+	}		tx_info;		/*0x30,rw,31:0*/
+	u64		tx_info_al;		/*0x38,rw,31:0*/
+	struct {
+		u32	rx_buff_pad1;
+		u32	rx_buff_pad2:8,
+			wptr:8,
+			rptr:8,
+			depth:8;
+	}		rx_buff;		/*0x40,ro,23:0*/
+	u64		rx_buff_al1;	/*0x48,ro,23:0*/
+	u64		rx_buff_al2;	/*0x50,ro,23:0*/
+	u64		int_update;		/*0x58,wo,31:0*/
+	u32		phy_data_pad;
+	u32		phy_data;		/*0x60,rw,16:0*/
+	u32		phy_reg_pad;
+	u32		phy_registers;	/*0x68,rw,9:0*/
+	u64		phy_trans_go;	/*0x70,wo,0:0*/
+	u64		backoff_seed;	/*0x78,wo,10:0*/
+	u64		imq_reserved[4];/*0x80,ro,64:0(x4)*/
+	/*===================================*/
+	u64		mac_addr;		/*0xA0,rw,47:0, I think it's MAC address, but I'm not sure*/
+	u64		mcast_addr;		/*0xA8,rw,47:0, This seems like secondary MAC address*/
+	u64		mcast_filter;	/*0xB0,rw,63:0*/
+	u64		tx_ring_base;	/*0xB8,rw,31:13*/
+	/* Following are read-only debugging info register */
+	u64		tx_pkt1_hdr;	/*0xC0,ro,63:0*/
+	u64		tx_pkt1_ptr[3];	/*0xC8,ro,63:0(x3)*/
+	u64		tx_pkt2_hdr;	/*0xE0,ro,63:0*/
+	u64		tx_pkt2_ptr[3];	/*0xE8,ro,63:0(x3)*/
+	/*===================================*/
+	u32		rx_pad;
+	u32		rx_fifo;
+	u64		reserved[31];
+}meth_regs;
+
+	/* Bits in METH_MAC */
+
+#define SGI_MAC_RESET		BIT(0)	/* 0: MAC110 active in run mode, 1: Global reset signal to MAC110 core is active */
+#define METH_PHY_FDX		BIT(1) /* 0: Disable full duplex, 1: Enable full duplex */
+#define METH_PHY_LOOP	BIT(2) /* 0: Normal operation, follows 10/100mbit and M10T/MII select, 1: loops internal MII bus */
+				       /*    selects ignored */
+#define METH_100MBIT		BIT(3) /* 0: 10meg mode, 1: 100meg mode */
+#define METH_PHY_MII		BIT(4) /* 0: MII selected, 1: SIA selected */
+				       /*   Note: when loopback is set this bit becomes collision control.  Setting this bit will */
+				       /*         cause a collision to be reported. */
+
+				       /* Bits 5 and 6 are used to determine the the Destination address filter mode */
+#define METH_ACCEPT_MY 0			/* 00: Accept PHY address only */
+#define METH_ACCEPT_MCAST 0x20	/* 01: Accept physical, broadcast, and multicast filter matches only */
+#define METH_ACCEPT_AMCAST 0x40	/* 10: Accept physical, broadcast, and all multicast packets */
+#define METH_PROMISC 0x60		/* 11: Promiscious mode */
+
+#define METH_PHY_LINK_FAIL	BIT(7) /* 0: Link failure detection disabled, 1: Hardware scans for link failure in PHY */
+
+#define METH_MAC_IPG	0x1ffff00
+
+#define METH_DEFAULT_IPG ((17<<15) | (11<<22) | (21<<8))
+						/* 0x172e5c00 */ /* 23, 23, 23 */ /*0x54A9500 *//*21,21,21*/
+				       /* Bits 8 through 14 are used to determine Inter-Packet Gap between "Back to Back" packets */
+				       /* The gap depends on the clock speed of the link, 80ns per increment for 100baseT, 800ns  */
+				       /* per increment for 10BaseT */
+
+				       /* Bits 15 through 21 are used to determine IPGR1 */
+
+				       /* Bits 22 through 28 are used to determine IPGR2 */
+
+#define METH_REV_SHIFT 29       /* Bits 29 through 31 are used to determine the revision */
+				       /* 000: Inital revision */
+				       /* 001: First revision, Improved TX concatenation */
+
+
+/* DMA control bits */
+#define METH_RX_OFFSET_SHIFT 12 /* Bits 12:14 of DMA control register indicate starting offset of packet data for RX operation */
+#define METH_RX_DEPTH_SHIFT 4 /* Bits 8:4 define RX fifo depth -- when # of RX fifo entries != depth, interrupt is generted */
+
+#define METH_DMA_TX_EN BIT(1) /* enable TX DMA */
+#define METH_DMA_TX_INT_EN BIT(0) /* enable TX Buffer Empty interrupt */
+#define METH_DMA_RX_EN BIT(15) /* Enable RX */
+#define METH_DMA_RX_INT_EN BIT(9) /* Enable interrupt on RX packet */
+
+
+/* RX status bits */
+
+#define METH_RX_ST_RCV_CODE_VIOLATION BIT(16)
+#define METH_RX_ST_DRBL_NBL BIT(17)
+#define METH_RX_ST_CRC_ERR BIT(18)
+#define METH_RX_ST_MCAST_PKT BIT(19)
+#define METH_RX_ST_BCAST_PKT BIT(20)
+#define METH_RX_ST_INV_PREAMBLE_CTX BIT(21)
+#define METH_RX_ST_LONG_EVT_SEEN BIT(22)
+#define METH_RX_ST_BAD_PACKET BIT(23)
+#define METH_RX_ST_CARRIER_EVT_SEEN BIT(24)
+#define METH_RX_ST_MCAST_FILTER_MATCH BIT(25)
+#define METH_RX_ST_PHYS_ADDR_MATCH BIT(26)
+
+#define METH_RX_STATUS_ERRORS \
+	( \
+	METH_RX_ST_RCV_CODE_VIOLATION| \
+	METH_RX_ST_CRC_ERR| \
+	METH_RX_ST_INV_PREAMBLE_CTX| \
+	METH_RX_ST_LONG_EVT_SEEN| \
+	METH_RX_ST_BAD_PACKET| \
+	METH_RX_ST_CARRIER_EVT_SEEN \
+	)
+	/* Bits in METH_INT */
+	/* Write _1_ to corresponding bit to clear */
+#define METH_INT_TX_EMPTY	BIT(0)	/* 0: No interrupt pending, 1: The TX ring buffer is empty */
+#define METH_INT_TX_PKT		BIT(1)	/* 0: No interrupt pending */
+					      	/* 1: A TX message had the INT request bit set, the packet has been sent. */
+#define METH_INT_TX_LINK_FAIL	BIT(2)	/* 0: No interrupt pending, 1: PHY has reported a link failure */
+#define METH_INT_MEM_ERROR	BIT(3)	/* 0: No interrupt pending */
+						/* 1: A memory error occurred durring DMA, DMA stopped, Fatal */
+#define METH_INT_TX_ABORT		BIT(4)	/* 0: No interrupt pending, 1: The TX aborted operation, DMA stopped, FATAL */
+#define METH_INT_RX_THRESHOLD	BIT(5)	/* 0: No interrupt pending, 1: Selected receive threshold condition Valid */
+#define METH_INT_RX_UNDERFLOW	BIT(6)	/* 0: No interrupt pending, 1: FIFO was empty, packet could not be queued */
+#define METH_INT_RX_OVERFLOW		BIT(7)	/* 0: No interrupt pending, 1: DMA FIFO Overflow, DMA stopped, FATAL */
+
+#define METH_INT_RX_RPTR_MASK 0x0001F00		/* Bits 8 through 12 alias of RX read-pointer */
+
+						/* Bits 13 through 15 are always 0. */
+
+#define METH_INT_TX_RPTR_MASK 0x1FF0000	        /* Bits 16 through 24 alias of TX read-pointer */
+
+#define METH_INT_SEQ_MASK    0x2E000000	        /* Bits 25 through 29 are the starting seq number for the message at the */
+						/* top of the queue */
+
+#define METH_ERRORS ( \
+	METH_INT_RX_OVERFLOW|	\
+	METH_INT_RX_UNDERFLOW|	\
+	METH_INT_MEM_ERROR|			\
+	METH_INT_TX_ABORT)
+
+#define METH_INT_MCAST_HASH		BIT(30) /* If RX DMA is enabled the hash select logic output is latched here */
+
+/* TX status bits */
+#define METH_TX_STATUS_DONE BIT(23) /* Packet was transmitted successfully */
+
+/* Tx command header bits */
+#define METH_TX_CMD_INT_EN BIT(24) /* Generate TX interrupt when packet is sent */
+
+/* Phy MDIO interface busy flag */
+#define MDIO_BUSY    BIT(16)
+#define MDIO_DATA_MASK 0xFFFF
+/* PHY defines */
+#define PHY_QS6612X    0x0181441    /* Quality TX */
+#define PHY_ICS1889    0x0015F41    /* ICS FX */
+#define PHY_ICS1890    0x0015F42    /* ICS TX */
+#define PHY_DP83840    0x20005C0    /* National TX */
diff -urN linux-2.4.20-pre6/drivers/net/pcmcia/wavelan_cs.c linux-2.4.20-pre7/drivers/net/pcmcia/wavelan_cs.c
--- linux-2.4.20-pre6/drivers/net/pcmcia/wavelan_cs.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/pcmcia/wavelan_cs.c	Thu Sep 12 20:01:44 2002
@@ -63,8 +63,7 @@
  *
  */
 
-#include <linux/ethtool.h>
-#include <asm/uaccess.h>
+/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
 #include "wavelan_cs.h"		/* Private header */
 
 /************************* MISC SUBROUTINES **************************/
diff -urN linux-2.4.20-pre6/drivers/net/pcmcia/wavelan_cs.h linux-2.4.20-pre7/drivers/net/pcmcia/wavelan_cs.h
--- linux-2.4.20-pre6/drivers/net/pcmcia/wavelan_cs.h	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/pcmcia/wavelan_cs.h	Thu Sep 12 20:01:44 2002
@@ -432,6 +432,7 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
+#include <linux/ethtool.h>
 
 #ifdef CONFIG_NET_PCMCIA_RADIO
 #include <linux/wireless.h>		/* Wireless extensions */
diff -urN linux-2.4.20-pre6/drivers/net/ppp_generic.c linux-2.4.20-pre7/drivers/net/ppp_generic.c
--- linux-2.4.20-pre6/drivers/net/ppp_generic.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/ppp_generic.c	Thu Sep 12 20:01:44 2002
@@ -404,19 +404,19 @@
 	remove_wait_queue(&pf->rwait, &wait);
 
 	if (skb == 0)
-		goto out;
+		goto err1;
 
 	ret = -EOVERFLOW;
 	if (skb->len > count)
-		goto outf;
+		goto err2;
 	ret = -EFAULT;
 	if (copy_to_user(buf, skb->data, skb->len))
-		goto outf;
+		goto err2;
 	ret = skb->len;
 
- outf:
+ err2:
 	kfree_skb(skb);
- out:
+ err1:
 	return ret;
 }
 
@@ -432,12 +432,12 @@
 	ret = -ENOMEM;
 	skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL);
 	if (skb == 0)
-		goto out;
+		goto err1;
 	skb_reserve(skb, pf->hdrlen);
 	ret = -EFAULT;
 	if (copy_from_user(skb_put(skb, count), buf, count)) {
 		kfree_skb(skb);
-		goto out;
+		goto err1;
 	}
 
 	skb_queue_tail(&pf->xq, skb);
@@ -453,7 +453,7 @@
 
 	ret = count;
 
- out:
+ err1:
 	return ret;
 }
 
@@ -806,7 +806,7 @@
 
 	npi = ethertype_to_npindex(ntohs(skb->protocol));
 	if (npi < 0)
-		goto outf;
+		goto err1;
 
 	/* Drop, accept or reject the packet */
 	switch (ppp->npmode[npi]) {
@@ -815,10 +815,10 @@
 	case NPMODE_QUEUE:
 		/* it would be nice to have a way to tell the network
 		   system to queue this one up for later. */
-		goto outf;
+		goto err1;
 	case NPMODE_DROP:
 	case NPMODE_ERROR:
-		goto outf;
+		goto err1;
 	}
 
 	/* Put the 2-byte PPP protocol number on the front,
@@ -828,7 +828,7 @@
 
 		ns = alloc_skb(skb->len + dev->hard_header_len, GFP_ATOMIC);
 		if (ns == 0)
-			goto outf;
+			goto err1;
 		skb_reserve(ns, dev->hard_header_len);
 		memcpy(skb_put(ns, skb->len), skb->data, skb->len);
 		kfree_skb(skb);
@@ -844,7 +844,7 @@
 	ppp_xmit_process(ppp);
 	return 0;
 
- outf:
+ err1:
 	kfree_skb(skb);
 	++ppp->stats.tx_dropped;
 	return 0;
@@ -1945,11 +1945,11 @@
 	if (copy_from_user(&data, (void *) arg, sizeof(data))
 	    || (data.length <= CCP_MAX_OPTION_LENGTH
 		&& copy_from_user(ccp_option, data.ptr, data.length)))
-		goto out;
+		goto err1;
 	err = -EINVAL;
 	if (data.length > CCP_MAX_OPTION_LENGTH
 	    || ccp_option[1] < 2 || ccp_option[1] > data.length)
-		goto out;
+		goto err1;
 
 	cp = find_compressor(ccp_option[0]);
 #ifdef CONFIG_KMOD
@@ -1960,7 +1960,7 @@
 	}
 #endif /* CONFIG_KMOD */
 	if (cp == 0)
-		goto out;
+		goto err1;
 	/*
 	 * XXX race: the compressor module could get unloaded between
 	 * here and when we do the comp_alloc or decomp_alloc call below.
@@ -1998,7 +1998,7 @@
 		}
 	}
 
- out:
+ err1:
 	return err;
 }
 
@@ -2144,15 +2144,15 @@
 	spin_lock(&compressor_list_lock);
 	ret = -EEXIST;
 	if (find_comp_entry(cp->compress_proto) != 0)
-		goto out;
+		goto err1;
 	ret = -ENOMEM;
 	ce = kmalloc(sizeof(struct compressor_entry), GFP_ATOMIC);
 	if (ce == 0)
-		goto out;
+		goto err1;
 	ret = 0;
 	ce->comp = cp;
 	list_add(&ce->list, &compressor_list);
- out:
+ err1:
 	spin_unlock(&compressor_list_lock);
 	return ret;
 }
@@ -2431,11 +2431,12 @@
 	down(&all_ppp_sem);
 	ppp = ppp_find_unit(unit);
 	if (ppp == 0)
-		goto out;
+		goto err1;
+
 	write_lock_bh(&pch->upl);
 	ret = -EINVAL;
 	if (pch->ppp != 0)
-		goto outl;
+		goto err2;
 
 	ppp_lock(ppp);
 	if (pch->file.hdrlen > ppp->file.hdrlen)
@@ -2450,9 +2451,9 @@
 	ppp_unlock(ppp);
 	ret = 0;
 
- outl:
+ err2:
 	write_unlock_bh(&pch->upl);
- out:
+ err1:
 	up(&all_ppp_sem);
 	return ret;
 }
diff -urN linux-2.4.20-pre6/drivers/net/sb1250-mac.c linux-2.4.20-pre7/drivers/net/sb1250-mac.c
--- linux-2.4.20-pre6/drivers/net/sb1250-mac.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/net/sb1250-mac.c	Thu Sep 12 20:01:44 2002
@@ -24,6 +24,9 @@
 */
 
 
+
+#define CONFIG_SBMAC_COALESCE
+
 /* A few user-configurable values.
    These may be modified when a driver module is loaded. */
 
@@ -41,6 +44,8 @@
 static int full_duplex[MAX_UNITS] = {-1, -1, -1};
 #endif
 
+static int int_pktcnt = 0;
+static int int_timeout = 0;
 
 /* Operational parameters that usually are not changed. */
 
@@ -53,21 +58,20 @@
 #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/slab.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 <linux/config.h>
+#include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/sibyte/sb1250.h>
@@ -75,7 +79,7 @@
 
 /* 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
+#ifdef CONFIG_SIBYTE_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"
@@ -96,12 +100,15 @@
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 
+MODULE_PARM(int_pktcnt, "i");
+MODULE_PARM(int_timeout, "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>
+#include <asm/sibyte/sb1250_scd.h>		/* Only to check SOC part number. */
 
 
 /**********************************************************************
@@ -152,7 +159,8 @@
 
 #define ETHER_ALIGN	2
 #define ETHER_ADDR_LEN	6
-#define ENET_PACKET_SIZE	1518
+#define ENET_PACKET_SIZE	1518 
+/*#define ENET_PACKET_SIZE	9216 */ 
 
 /**********************************************************************
  *  DMA Descriptor structure
@@ -179,8 +187,13 @@
 	
 	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 */
+	int		 sbdma_txdir;       /* direction (1=transmit) */
+	int		 sbdma_maxdescr;	/* total # of descriptors in ring */
+#ifdef CONFIG_SBMAC_COALESCE
+        int              sbdma_int_pktcnt;  /* # descriptors rx before interrupt*/
+        int              sbdma_int_timeout; /* # usec rx interrupt */
+#endif
+
 	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 */
@@ -208,11 +221,13 @@
  ********************************************************************* */
 
 struct sbmac_softc {
+	
 	/*
 	 * Linux-specific things
 	 */
-	struct net_device *sbm_dev;
-	spinlock_t sbm_lock;
+	
+	struct net_device *sbm_dev;		/* pointer to linux device */
+	spinlock_t sbm_lock;		/* spin lock */
 	struct timer_list sbm_timer;     	/* for monitoring MII */
 	struct net_device_stats sbm_stats; 
 	int sbm_devflags;			/* current device flags */
@@ -222,15 +237,16 @@
         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 */
@@ -239,15 +255,18 @@
 	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;
+	int              rx_hw_checksum;
+	int 		 sbe_idx;
+	
 };
 
 
@@ -264,7 +283,7 @@
 			  int chan,
 			  int txrx,
 			  int maxdescr);
-static void sbdma_channel_start(sbmacdma_t *d);
+static void sbdma_channel_start(sbmacdma_t *d, int rxtx);
 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);
@@ -305,6 +324,9 @@
  *  Globals
  ********************************************************************* */
 
+static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
+static uint64_t chip_revision;
+
 
 /**********************************************************************
  *  MDIO constants
@@ -325,7 +347,7 @@
 #define BMCR_DUPLEX    0x0100
 #define BMCR_COLTEST   0x0080
 #define BMCR_SPEED1    0x0040
-#define BMCR_SPEED1000 (BMCR_SPEED1|BMCR_SPEED0)
+#define BMCR_SPEED1000 (BMCR_SPEED1)
 #define BMCR_SPEED100  (BMCR_SPEED0)
 #define BMCR_SPEED10 	0
 
@@ -434,8 +456,10 @@
 
 #define M_MAC_MDIO_DIR_OUTPUT	0		/* for clarity */
 
+#define ENABLE 		1
+#define DISABLE		0
 
-/*
+/**********************************************************************
  *  SBMAC_MII_SYNC(s)
  *  
  *  Synchronize with the MII - send a pattern of bits to the MII
@@ -446,7 +470,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbmac_mii_sync(struct sbmac_softc *s)
 {
 	int cnt;
@@ -462,7 +487,7 @@
 	}
 }
 
-/*
+/**********************************************************************
  *  SBMAC_MII_SENDDATA(s,data,bitcnt)
  *  
  *  Send some bits to the MII.  The bits to be sent are right-
@@ -472,7 +497,8 @@
  *  	   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;
@@ -494,7 +520,9 @@
 	}
 }
 
-/*
+
+
+/**********************************************************************
  *  SBMAC_MII_READ(s,phyaddr,regidx)
  *  
  *  Read a PHY register.
@@ -506,7 +534,8 @@
  *  	   
  *  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;
@@ -578,7 +607,7 @@
 }
 
 
-/*
+/**********************************************************************
  *  SBMAC_MII_WRITE(s,phyaddr,regidx,regval)
  *  
  *  Write a value to a PHY register.
@@ -591,7 +620,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
 			    unsigned int regval)
 {
@@ -610,7 +640,7 @@
 
 
 
-/*
+/**********************************************************************
  *  SBDMA_INITCTX(d,s,chan,txrx,maxdescr)
  *  
  *  Initialize a DMA channel context.  Since there are potentially
@@ -626,7 +656,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbdma_initctx(sbmacdma_t *d,
 			  struct sbmac_softc *s,
 			  int chan,
@@ -641,6 +672,52 @@
 	d->sbdma_channel   = chan;
 	d->sbdma_txdir     = txrx;
 	
+	/* RMON clearing */
+	s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING;
+
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0);
+	SBMAC_WRITECSR(PKSEG1(
+        A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0);
+
 	/* 
 	 * initialize register pointers 
 	 */
@@ -648,7 +725,7 @@
 	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));
+		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1));
 	d->sbdma_dscrbase = 
 		PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE));
 	d->sbdma_dscrcnt = 
@@ -680,42 +757,120 @@
 	
 	memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *));
 	
+#ifdef CONFIG_SBMAC_COALESCE
+        /*
+         * Setup Rx DMA coalescing defaults
+         */
+
+        if ( txrx == DMA_RX ) {
+		if ( int_pktcnt ) {
+                	d->sbdma_int_pktcnt = int_pktcnt;
+		        }
+		else {
+                	d->sbdma_int_pktcnt = 1;
+		        }
+
+		if ( int_timeout ) {
+		        d->sbdma_int_timeout = int_timeout;
+		        }
+		else {
+		        d->sbdma_int_timeout = 0;
+		    }
+	        }
+        else {
+                d->sbdma_int_pktcnt = 0;
+                d->sbdma_int_timeout = 0;
+	        }
+#endif
+
 }
 
-/*
+/**********************************************************************
  *  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
+ *         rxtx - DMA_RX or DMA_TX depending on what type of channel
+ *  	   
+ *  Return value:
+ *  	   nothing
+ ********************************************************************* */
+
+static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
+{
+    /*
+     * Turn on the DMA channel
+     */
+	
+#ifdef CONFIG_SBMAC_COALESCE
+    if (rxtx == DMA_RX) {
+        SBMAC_WRITECSR(d->sbdma_config1,
+		       V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
+		       0);
+        SBMAC_WRITECSR(d->sbdma_config0,
+                       M_DMA_EOP_INT_EN |
+                       V_DMA_RINGSZ(d->sbdma_maxdescr) |
+                       V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) |
+                       0);
+	}
+    else {
+	SBMAC_WRITECSR(d->sbdma_config1,0);
+	SBMAC_WRITECSR(d->sbdma_config0,
+		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
+		       0);
+	}
+#else
+    SBMAC_WRITECSR(d->sbdma_config1,0);
+    SBMAC_WRITECSR(d->sbdma_config0,
+		   V_DMA_RINGSZ(d->sbdma_maxdescr) |
+		   0);
+#endif
+
+	
+    SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
+	
+    /*
+     * Initialize ring pointers
+     */
+	
+    d->sbdma_addptr = d->sbdma_dscrtable;
+    d->sbdma_remptr = d->sbdma_dscrtable;
+}
+
+/**********************************************************************
+ *  SBDMA_CHANNEL_STOP(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)
+ ********************************************************************* */
+
+static void sbdma_channel_stop(sbmacdma_t *d)
 {
 	/*
-	 * Turn on the DMA channel
+	 * Turn off the DMA channel
 	 */
 	
 	SBMAC_WRITECSR(d->sbdma_config1,0);
 	
-	SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
+	SBMAC_WRITECSR(d->sbdma_dscrbase,0);
 	
-	SBMAC_WRITECSR(d->sbdma_config0,
-		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
-		       0);
+	SBMAC_WRITECSR(d->sbdma_config0,0);
 	
 	/*
-	 * Initialize ring pointers
+	 * Zero ring pointers
 	 */
 	
-	d->sbdma_addptr = d->sbdma_dscrtable;
-	d->sbdma_remptr = d->sbdma_dscrtable;
+	d->sbdma_addptr = 0;
+	d->sbdma_remptr = 0;
 }
 
-
 static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
 {
 	unsigned long addr;
@@ -728,7 +883,8 @@
 	skb_reserve(skb,newaddr-addr+offset);
 }
 
-/*
+
+/**********************************************************************
  *  SBDMA_ADD_RCVBUFFER(d,sb)
  *  
  *  Add a buffer to the specified DMA channel.   For receive channels,
@@ -741,7 +897,9 @@
  *  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;
@@ -774,7 +932,7 @@
 	 *
 	 *    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 
+	 *    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,
@@ -808,9 +966,18 @@
 	 * fill in the descriptor 
 	 */
 	
+#ifdef CONFIG_SBMAC_COALESCE
+        /*
+         * Do not interrupt per DMA transfer.
+         */
+        dsc->dscr_a = KVTOPHYS(sb_new->tail) |
+                V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
+                0;
+#else
 	dsc->dscr_a = KVTOPHYS(sb_new->tail) |
 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
 		M_DMA_DSCRA_INTERRUPT;
+#endif
 	
 	/* receiving: no options */
 	dsc->dscr_b = 0;
@@ -836,7 +1003,7 @@
 	return 0;					/* we did it */
 }
 
-/*
+/**********************************************************************
  *  SBDMA_ADD_TXBUFFER(d,sb)
  *  
  *  Add a transmit buffer to the specified DMA channel, causing a
@@ -849,7 +1016,9 @@
  *  Return value:
  *  	   0 transmit queued successfully
  *  	   otherwise error code
- */
+ ********************************************************************* */
+
+
 static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
 {
 	sbdmadscr_t *dsc;
@@ -922,6 +1091,9 @@
 	return 0;					/* we did it */
 }
 
+
+
+
 /**********************************************************************
  *  SBDMA_EMPTYRING(d)
  *  
@@ -960,17 +1132,19 @@
  *  	   
  *  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;
+	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.  
@@ -984,7 +1158,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d)
 {
 	int curidx;
@@ -1004,72 +1179,97 @@
 		 * 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;
-
+		
+		if (curidx == hwidx) break;
+		
 		/*
 		 * Otherwise, get the packet's sk_buff ptr back
 		 */
-		dsc = d->sbdma_dscrtable + curidx;
+		
+		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 {
+			
+			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);
+                            if (sc->rx_hw_checksum == ENABLE) {
+			    /* if the ip checksum is good indicate in skb.
+		                else set CHECKSUM_NONE as device failed to
+					checksum the packet */
+
+			       if (((dsc->dscr_b) |M_DMA_ETHRX_BADTCPCS) ||
+			     	  ((dsc->dscr_a)| M_DMA_ETHRX_BADIP4CS)){
+				  sb->ip_summed = CHECKSUM_NONE;
+			       } else {
+				 printk(KERN_DEBUG "hw checksum fail .\n");
+				 sb->ip_summed = CHECKSUM_UNNECESSARY;
+			       }
+			    } /*rx_hw_checksum */
+
+			    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.  
@@ -1084,7 +1284,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d)
 {
 	int curidx;
@@ -1093,8 +1294,8 @@
 	struct sk_buff *sb;
 	unsigned long flags;
 
-	spin_lock_irqsave(&sc->sbm_lock, flags);
-
+	spin_lock_irqsave(&(sc->sbm_lock), flags);
+	
 	for (;;) {
 		/* 
 		 * figure out where we are (as an index) and where
@@ -1125,59 +1326,64 @@
 			*/
 			  
 			uint64_t tmp = SBMAC_READCSR(d->sbdma_curdscr);
-			if (!tmp)
+			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;
+		
+		if (curidx == hwidx) break;
 		
 		/*
 		 * Otherwise, get the packet's sk_buff ptr back
 		 */
-		dsc = d->sbdma_dscrtable + curidx;
+		
+		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);
+	
+	spin_unlock_irqrestore(&(sc->sbm_lock), flags);
+	
 }
 
 
 
-/*
+/**********************************************************************
  *  SBMAC_INITCTX(s)
  *  
  *  Initialize an Ethernet context structure - this is called
@@ -1190,7 +1396,8 @@
  *  	   
  *  Return value:
  *  	   0
- */
+ ********************************************************************* */
+
 static int sbmac_initctx(struct sbmac_softc *s)
 {
 	
@@ -1220,8 +1427,8 @@
 	 * 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);
+	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
@@ -1240,6 +1447,7 @@
 	return 0;
 }
 
+
 static void sbdma_uninitctx(struct sbmacdma_s *d)
 {
 	if (d->sbdma_dscrtable) {
@@ -1256,11 +1464,12 @@
 
 static void sbmac_uninitctx(struct sbmac_softc *sc)
 {
-	sbdma_uninitctx(&sc->sbm_txdma);
-	sbdma_uninitctx(&sc->sbm_rxdma);
+	sbdma_uninitctx(&(sc->sbm_txdma));
+	sbdma_uninitctx(&(sc->sbm_rxdma));
 }
 
-/*
+
+/**********************************************************************
  *  SBMAC_CHANNEL_START(s)
  *  
  *  Start packet processing on this MAC.
@@ -1270,7 +1479,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbmac_channel_start(struct sbmac_softc *s)
 {
 	uint64_t reg;
@@ -1308,8 +1518,14 @@
 		M_MAC_SS_EN |
 		0;
 	
+	/* 
+	 * Be sure that RD_THRSH+WR_THRSH <= 32
+	 * Use a larger RD_THRSH for gigabit
+	 */
+
 	fifo = V_MAC_TX_WR_THRSH(4) |	/* Must be '4' or '8' */
-		V_MAC_TX_RD_THRSH(4) |
+		((s->sbm_speed == sbmac_speed_1000)
+		 ? V_MAC_TX_RD_THRSH(28) : 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' */
@@ -1395,59 +1611,82 @@
 	/*
 	 * Initialize DMA channels (rings should be ok now)
 	 */
-	sbdma_channel_start(&s->sbm_rxdma);
-	sbdma_channel_start(&s->sbm_txdma);
-
+	
+	sbdma_channel_start(&(s->sbm_rxdma), DMA_RX);
+	sbdma_channel_start(&(s->sbm_txdma), DMA_TX);
+	
 	/*
 	 * 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);
-
+	
+	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);
+	
+	
 
+
+#ifdef CONFIG_SBMAC_COALESCE
+	/*
+	 * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
+	 */
+	SBMAC_WRITECSR(s->sbm_imr,
+		       (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0));
+#else
 	/*
 	 * 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));
-
+#endif
+	
 	/* 
 	 * 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)
+	
+	if (s->sbm_devflags & IFF_PROMISC) {
 		sbmac_promiscuous_mode(s,1);
+	}
+	
 }
 
-/*
+
+/**********************************************************************
  *  SBMAC_CHANNEL_STOP(s)
  *  
  *  Stop packet processing on this MAC.
@@ -1457,11 +1696,10 @@
  *  	   
  *  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;
@@ -1477,22 +1715,27 @@
 	
 	/* 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);
+	SBMAC_WRITECSR(s->sbm_macenable,0);
 	
 	/* We're stopped now. */
 	
 	s->sbm_state = sbmac_state_off;
 	
+	/*
+	 * Stop DMA channels (rings should be ok now)
+	 */
+	
+	sbdma_channel_stop(&(s->sbm_rxdma));
+	sbdma_channel_stop(&(s->sbm_txdma));
 	
 	/* Empty the receive and transmit rings */
 	
-	sbdma_emptyring(&s->sbm_rxdma);
-	sbdma_emptyring(&s->sbm_txdma);
+	sbdma_emptyring(&(s->sbm_rxdma));
+	sbdma_emptyring(&(s->sbm_txdma));
+	
 }
 
-/*
+/**********************************************************************
  *  SBMAC_SET_CHANNEL_STATE(state)
  *  
  *  Set the channel's state ON or OFF
@@ -1502,7 +1745,7 @@
  *  	   
  *  Return value:
  *  	   old state
- */
+ ********************************************************************* */
 static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
 					     sbmac_state_t state)
 {
@@ -1535,7 +1778,7 @@
 }
 
 
-/*
+/**********************************************************************
  *  SBMAC_PROMISCUOUS_MODE(sc,onoff)
  *  
  *  Turn on or off promiscuous mode
@@ -1546,7 +1789,8 @@
  *  	   
  *  Return value:
  *  	   nothing
- */
+ ********************************************************************* */
+
 static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff)
 {
 	uint64_t reg;
@@ -1565,6 +1809,36 @@
 	}
 }
 
+/**********************************************************************
+ *  SBMAC_SETIPHDR_OFFSET(sc,onoff)
+ *  
+ *  Set the iphdr offset as 15 assuming ethernet encapsulation
+ *  
+ *  Input parameters: 
+ *  	   sc - softc
+ *  	   
+ *  Return value:
+ *  	   nothing
+ ********************************************************************* */
+
+static void sbmac_set_iphdr_offset(struct sbmac_softc *sc)
+{
+	uint64_t reg;
+	
+	reg = SBMAC_READCSR(sc->sbm_rxfilter);
+	reg &= ~M_MAC_IPHDR_OFFSET;
+	/* Hard code the off set to 15 for now */
+	reg |= 15 << S_MAC_IPHDR_OFFSET;
+	SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	
+	/* read system identification to determine revision */
+	if (sb1250_pass >= K_SYS_REVISION_PASS2) {
+		printk(KERN_INFO "pass2 - enabling Rx rcv tcp checksum\n");
+		sc->rx_hw_checksum = ENABLE;
+	} else {
+		sc->rx_hw_checksum = DISABLE;
+	}
+}
 
 
 #if 0
@@ -1582,15 +1856,17 @@
 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);
+	
+	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
@@ -1601,13 +1877,14 @@
  *  	   
  *  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); 
@@ -1619,12 +1896,12 @@
 	reg |= (uint64_t) *(--ptr); 
 	reg <<= 8;
 	reg |= (uint64_t) *(--ptr); 
-
+	
 	return reg;
 }
 
 
-/*
+/**********************************************************************
  *  SBMAC_SET_SPEED(s,speed)
  *  
  *  Configure LAN speed for the specified MAC.
@@ -1637,7 +1914,8 @@
  *  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;
@@ -1728,8 +2006,7 @@
  *  	   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)
+static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc)
 {
 	uint64_t cfg;
 	
@@ -1810,37 +2087,75 @@
 	return 1;
 }
 
+
+
+
+/**********************************************************************
+ *  SBMAC_INTR()
+ *  
+ *  Interrupt handler for MAC interrupts
+ *  
+ *  Input parameters: 
+ *  	   MAC structure
+ *  	   
+ *  Return value:
+ *  	   nothing
+ ********************************************************************* */
 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;
+	struct sbmac_softc *sc = (struct sbmac_softc *) (dev->priv);
 	uint64_t isr;
-
+	
 	for (;;) {
+		
 		/*
-		 * Read the ISR (this clears the bits in the real register)
+		 * Read the ISR (this clears the bits in the real
+		 * register, except for counter addr)
 		 */
-		isr = SBMAC_READCSR(sc->sbm_isr);
-
-		if (isr == 0)
-			break;
-
+		
+		isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
+		
+		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);
-
+		
+		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);
+
+		/*
+		 * It's important to test all the bits (or at least the
+		 * EOP_SEEN bit) when deciding to do the RX process
+		 * particularly when coalescing, to make sure we
+		 * take care of the following:
+		 *
+		 * If you have some packets waiting (have been received
+		 * but no interrupt) and get a TX interrupt before
+		 * the RX timer or counter expires, reading the ISR
+		 * above will clear the timer and counter, and you
+		 * won't get another interrupt until a packet shows
+		 * up to start the timer again.  Testing
+		 * EOP_SEEN here takes care of this case.
+		 * (EOP_SEEN is part of M_MAC_INT_CHANNEL << S_MAC_RX_CH0)
+		 */
+		 
+		
+		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 
@@ -1852,29 +2167,31 @@
  *  	   
  *  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);
-
+	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))) {
+	
+	if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) {
+		/* XXX save skb that we could not send */
 		netif_stop_queue(dev);
 		spin_unlock_irq(&sc->sbm_lock);
 
 		return 1;
 	}
-
+	
 	dev->trans_start = jiffies;
-
-	spin_unlock_irq(&sc->sbm_lock);
-
+	
+	spin_unlock_irq (&sc->sbm_lock);
+	
 	return 0;
 }
 
@@ -1968,6 +2285,8 @@
 	}
 }
 
+
+
 #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR)
 /**********************************************************************
  *  SBMAC_PARSE_XDIGIT(str)
@@ -1993,6 +2312,20 @@
 	return digit;
 }
 
+/**********************************************************************
+ *  SBMAC_PARSE_HWADDR(str,hwaddr)
+ *  
+ *  Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte
+ *  Ethernet address.
+ *  
+ *  Input parameters: 
+ *  	   str - string
+ *  	   hwaddr - pointer to hardware address
+ *  	   
+ *  Return value:
+ *  	   0 if ok, else -1
+ ********************************************************************* */
+
 static int sbmac_parse_hwaddr(char *str,u_char *hwaddr)
 {
 	int digit1,digit2;
@@ -2024,6 +2357,27 @@
 }
 #endif
 
+static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
+{
+        if (new_mtu >  ENET_PACKET_SIZE)
+                return -EINVAL;
+        _dev->mtu = new_mtu;
+	printk(KERN_INFO "changing the mtu to %d\n", new_mtu);
+        return 0;
+}
+
+/**********************************************************************
+ *  SBMAC_INIT(dev)
+ *  
+ *  Attach routine - init hardware and hook ourselves into linux
+ *  
+ *  Input parameters: 
+ *  	   dev - net_device structure
+ *  	   
+ *  Return value:
+ *  	   status
+ ********************************************************************* */
+
 static int sbmac_init(struct net_device *dev)
 {
 	struct sbmac_softc *sc;
@@ -2086,7 +2440,7 @@
 	 * Set up Linux device callins
 	 */
 	
-	spin_lock_init(&sc->sbm_lock);
+	spin_lock_init(&(sc->sbm_lock));
 	
 	ether_setup(dev);
 	dev->open               = sbmac_open;
@@ -2097,11 +2451,22 @@
 	dev->do_ioctl           = sbmac_mii_ioctl;
 	dev->tx_timeout         = sbmac_tx_timeout;
 	dev->watchdog_timeo     = TX_TIMEOUT;
+
+	dev->change_mtu         = sb1250_change_mtu;
+
+	if (sb1250_pass >= K_SYS_REVISION_PASS3) {
+		/* In pass3 we do dumb checksum in TX */
+		dev->features |= NETIF_F_IP_CSUM;
+	}
+
+        /* This is needed for PASS2 for Rx H/W checksum feature */
+	sbmac_set_iphdr_offset( sc);
 	
 	return 0;
 	
 }
 
+
 static int sbmac_open(struct net_device *dev)
 {
 	struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv;
@@ -2154,101 +2519,116 @@
 	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;
+    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;
+    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 ((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 ((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;
+    if (chg == 0) return 0;
 
-	p += sprintf(p,"Link speed: ");
+    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 (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);
+#ifdef CONFIG_NET_SB1250_MAC_QUIET
+    noisy = 0;
+#endif
+    if (noisy) {
+	    printk(KERN_INFO "%s: %s\n",s->sbm_dev->name,buffer);
+	    }
 
-		return 1;
+    return 1;
 }
 
+
+
+
 static void sbmac_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
@@ -2295,6 +2675,7 @@
 	add_timer(&sc->sbm_timer);
 }
 
+
 static void sbmac_tx_timeout (struct net_device *dev)
 {
 	struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv;
@@ -2310,6 +2691,9 @@
 	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;
@@ -2324,6 +2708,8 @@
 	return &sc->sbm_stats;
 }
 
+
+
 static void sbmac_set_rx_mode(struct net_device *dev)
 {
 	unsigned long flags;
@@ -2355,6 +2741,7 @@
 	/*
 	 * Program the multicasts.  Do this every time.
 	 */
+	
 	sbmac_setmulti(sc);
 	
 }
@@ -2399,33 +2786,36 @@
 {
 	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)
+	
+	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);
-
+	
+	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)
@@ -2451,6 +2841,7 @@
 	int macidx = 0;
 	struct net_device *dev;
 	sbmac_port_t port;
+	int chip_max_units;
 	
 	/*
 	 * For bringup when not using the firmware, we can pre-fill
@@ -2471,8 +2862,25 @@
 	 * Walk through the Ethernet controllers and find
 	 * those who have their MAC addresses set.
 	 */
-	
-	for (idx = 0; idx < MAX_UNITS; idx++) {
+	chip_revision = SBMAC_READCSR(PKSEG1(A_SCD_SYSTEM_REVISION));
+	switch ((int)G_SYS_PART(chip_revision)) {
+	case 0x1150:
+	case 0x1250:
+		chip_max_units = 3;
+		break;
+	case 0x1120:
+	case 0x1125:
+	case 0x1126:
+		chip_max_units = 2;
+		break;
+	default:
+		chip_max_units = 0;
+		break;
+	}
+	if (chip_max_units > MAX_UNITS)
+		chip_max_units = MAX_UNITS;
+
+	for (idx = 0; idx < chip_max_units; idx++) {
 
 	        /*
 	         * This is the base address of the MAC.
@@ -2486,16 +2894,20 @@
 		 * If we find a zero, skip this MAC.
 		 */
 
-		if (SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)) == 0) {
+		sbmac_orig_hwaddr[idx] = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR));
+		if (sbmac_orig_hwaddr[idx] == 0) {
+		    printk( KERN_DEBUG "sbmac: not configuring MAC at %x\n",(uint32_t)port);
 		    continue;
-		    }
+		}
 
 		/*
 		 * Okay, cool.  Initialize this MAC.
 		 */
 
 		dev = init_etherdev(NULL,sizeof(struct sbmac_softc));
-		if (!dev) break;			/* problems, get out now. */
+		if (!dev) 
+		  return -ENOMEM;	/* return ENOMEM */
+
 		dev->irq = K_INT_MAC_0 + idx;
 		dev->base_addr = port;
 		dev->mem_end = 0;
@@ -2520,6 +2932,7 @@
 {
 	int idx;
 	struct net_device *dev;
+	sbmac_port_t port;
 	for (idx = 0; idx < MAX_UNITS; idx++) {
 		dev = dev_sbmac[idx];
 		if (dev == NULL) continue;
@@ -2530,8 +2943,10 @@
 			
 			sbmac_uninitctx(sc);
 			
-			KFREE(sc);
 		}
+
+	        port = A_MAC_CHANNEL_BASE(idx);
+		SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] );
 		KFREE(dev);
 		dev_sbmac[idx] = NULL;
 	}
diff -urN linux-2.4.20-pre6/drivers/net/sgiseeq.h linux-2.4.20-pre7/drivers/net/sgiseeq.h
--- linux-2.4.20-pre6/drivers/net/sgiseeq.h	Sat May 13 08:29:40 2000
+++ linux-2.4.20-pre7/drivers/net/sgiseeq.h	Thu Sep 12 20:01:44 2002
@@ -1,4 +1,4 @@
-/* $Id: sgiseeq.h,v 1.4 1999/10/09 00:01:24 ralf Exp $
+/*
  * sgiseeq.h: Defines for the Seeq8003 ethernet controller.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
diff -urN linux-2.4.20-pre6/drivers/net/tg3.c linux-2.4.20-pre7/drivers/net/tg3.c
--- linux-2.4.20-pre6/drivers/net/tg3.c	Thu Sep 12 20:01:34 2002
+++ linux-2.4.20-pre7/drivers/net/tg3.c	Thu Sep 12 20:01:44 2002
@@ -4878,9 +4878,15 @@
 
 	rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC |
 				  RX_MODE_KEEP_VLAN_TAG);
+#if TG3_VLAN_TAG_USED
 	if (!tp->vlgrp)
 		rx_mode |= RX_MODE_KEEP_VLAN_TAG;
-
+#else
+	/* By definition, VLAN is disabled always in this
+	* case.
+	*/
+	rx_mode |= RX_MODE_KEEP_VLAN_TAG;
+#endif 
 	if (dev->flags & IFF_PROMISC) {
 		/* Promiscuous mode. */
 		rx_mode |= RX_MODE_PROMISC;
diff -urN linux-2.4.20-pre6/drivers/pci/Makefile linux-2.4.20-pre7/drivers/pci/Makefile
--- linux-2.4.20-pre6/drivers/pci/Makefile	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/pci/Makefile	Thu Sep 12 20:01:45 2002
@@ -27,7 +27,7 @@
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
 obj-$(CONFIG_PARISC) += setup-bus.o
 obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
-obj-$(CONFIG_ALL_PPC) += setup-bus.o
+obj-$(CONFIG_PPC32) += setup-irq.o
 obj-$(CONFIG_SGI_IP27) += setup-irq.o
 obj-$(CONFIG_SGI_IP32) += setup-irq.o
 
diff -urN linux-2.4.20-pre6/drivers/pci/pci.c linux-2.4.20-pre7/drivers/pci/pci.c
--- linux-2.4.20-pre6/drivers/pci/pci.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/pci/pci.c	Thu Sep 12 20:01:45 2002
@@ -1131,6 +1131,13 @@
 	if (!dev)		/* It's a host bus, nothing to read */
 		return;
 
+	if (dev->transparent) {
+		printk("Transparent bridge - %s\n", dev->name);
+		for(i = 0; i < 4; i++)
+			child->resource[i] = child->parent->resource[i];
+		return;
+	}
+
 	for(i=0; i<3; i++)
 		child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
 
@@ -1153,13 +1160,6 @@
 		res->start = base;
 		res->end = limit + 0xfff;
 		res->name = child->name;
-	} else {
-		/*
-		 * Ugh. We don't know enough about this bridge. Just assume
-		 * that it's entirely transparent.
-		 */
-		printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 0);
-		child->resource[0] = child->parent->resource[0];
 	}
 
 	res = child->resource[1];
@@ -1172,10 +1172,6 @@
 		res->start = base;
 		res->end = limit + 0xfffff;
 		res->name = child->name;
-	} else {
-		/* See comment above. Same thing */
-		printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 1);
-		child->resource[1] = child->parent->resource[1];
 	}
 
 	res = child->resource[2];
@@ -1203,10 +1199,6 @@
 		res->start = base;
 		res->end = limit + 0xfffff;
 		res->name = child->name;
-	} else {
-		/* See comments above */
-		printk(KERN_ERR "Unknown bridge resource %d: assuming transparent\n", 2);
-		child->resource[2] = child->parent->resource[2];
 	}
 }
 
@@ -1392,6 +1384,10 @@
 	case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
 		if (class != PCI_CLASS_BRIDGE_PCI)
 			goto bad;
+		/* The PCI-to-PCI bridge spec requires that subtractive
+		   decoding (i.e. transparent) bridge must have programming
+		   interface code of 0x01. */ 
+		dev->transparent = ((class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
 		break;
 
diff -urN linux-2.4.20-pre6/drivers/pci/quirks.c linux-2.4.20-pre7/drivers/pci/quirks.c
--- linux-2.4.20-pre6/drivers/pci/quirks.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/pci/quirks.c	Thu Sep 12 20:01:45 2002
@@ -471,6 +471,11 @@
 	r -> end = 0xffffff;
 }
 
+static void __init quirk_transparent_bridge(struct pci_dev *dev)
+{
+	dev->transparent = 1;
+}
+
 /*
  *  The main table of quirks.
  */
@@ -525,6 +530,13 @@
 
 	{ PCI_FIXUP_FINAL, 	PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7410,	quirk_amd_ioapic },
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering },
+	/*
+	 * i82380FB mobile docking controller: its PCI-to-PCI bridge
+	 * is subtractive decoding (transparent), and does indicate this
+	 * in the ProgIf. Unfortunately, the ProgIf value is wrong - 0x80
+	 * instead of 0x01.
+	 */
+	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82380FB,	quirk_transparent_bridge },
 
 	{ 0 }
 };
diff -urN linux-2.4.20-pre6/drivers/pcmcia/au1000_generic.c linux-2.4.20-pre7/drivers/pcmcia/au1000_generic.c
--- linux-2.4.20-pre6/drivers/pcmcia/au1000_generic.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/pcmcia/au1000_generic.c	Thu Sep 12 20:01:45 2002
@@ -59,6 +59,7 @@
 static int pc_debug;
 #endif
 
+MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>");
 MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
 
@@ -84,7 +85,7 @@
 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_poll_event(unsigned long data);
 static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
 static struct tq_struct au1000_pcmcia_task;
 
@@ -141,6 +142,11 @@
 
 	printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);
 
+#ifndef CONFIG_64BIT_PHYS_ADDR
+	printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n");
+	return -1;
+#endif
+
 	CardServices(GetCardServicesInfo, &info);
 
 	if(info.Revision!=CS_RELEASE_CODE){
@@ -148,10 +154,8 @@
 		return -1;
 	}
 
-#ifdef CONFIG_MIPS_PB1000
-	pcmcia_low_level=&pb1000_pcmcia_ops;
-#elif defined(CONFIG_MIPS_PB1500)
-	pcmcia_low_level=&pb1500_pcmcia_ops;
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
+	pcmcia_low_level=&pb1x00_pcmcia_ops;
 #else
 #error Unsupported AU1000 board.
 #endif
@@ -162,12 +166,7 @@
 		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);
+	/* NOTE: the chip select must already be setup */
 
 	pcmcia_socket = 
 		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
@@ -179,6 +178,11 @@
 	memset(pcmcia_socket, 0,
 			sizeof(struct au1000_pcmcia_socket) * socket_count);
 			
+	/* 
+	 * Assuming max of 2 sockets, which the Au1000 supports.
+	 * WARNING: the Pb1000 has two sockets, and both work, but you
+	 * can't use them both at the same time due to glue logic conflicts.
+	 */
 	for(i=0; i < socket_count; i++) {
 
 		if(pcmcia_low_level->socket_state(i, &state)<0){
@@ -190,13 +194,15 @@
 		
 		if (i == 0) {
 			pcmcia_socket[i].virt_io = 
-				(u32)ioremap(0xC0000000, 0x1000);
-			pcmcia_socket[i].phys_attr = 0xC4000000;
-			pcmcia_socket[i].phys_mem = 0xC8000000;
+				(u32)ioremap((ioaddr_t)0xF00000000, 0x1000);
+			pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000;
+			pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000;
 		}
 		else  {
-			printk(KERN_ERR "au1000: socket 1 not supported\n");
-			return 1;
+			pcmcia_socket[i].virt_io = 
+				(u32)ioremap((ioaddr_t)0xF08000000, 0x1000);
+			pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000;
+			pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000;
 		}
 	}
 
@@ -299,7 +305,7 @@
 };
 
 
-static void au1000_pcmcia_poll_event(u32 dummy)
+static void au1000_pcmcia_poll_event(unsigned long dummy)
 {
 	poll_timer.function = au1000_pcmcia_poll_event;
 	poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
diff -urN linux-2.4.20-pre6/drivers/pcmcia/au1000_pb1000.c linux-2.4.20-pre7/drivers/pcmcia/au1000_pb1000.c
--- linux-2.4.20-pre6/drivers/pcmcia/au1000_pb1000.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/pcmcia/au1000_pb1000.c	Wed Dec 31 16:00:00 1969
@@ -1,307 +0,0 @@
-/*
- *
- * 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 -urN linux-2.4.20-pre6/drivers/pcmcia/au1000_pb1x00.c linux-2.4.20-pre7/drivers/pcmcia/au1000_pb1x00.c
--- linux-2.4.20-pre6/drivers/pcmcia/au1000_pb1x00.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/pcmcia/au1000_pb1x00.c	Thu Sep 12 20:01:45 2002
@@ -0,0 +1,411 @@
+/*
+ *
+ * Alchemy Semi Pb1x00 boards specific pcmcia routines.
+ *
+ * Copyright 2002 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/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>
+
+#ifdef CONFIG_MIPS_PB1000
+#include <asm/pb1000.h>
+#define PCMCIA_IRQ AU1000_GPIO_15
+#elif defined (CONFIG_MIPS_PB1500)
+#include <asm/pb1500.h>
+#define PCMCIA_IRQ AU1000_GPIO_11   /* fixme */
+#elif defined (CONFIG_MIPS_PB1100)
+#include <asm/pb1100.h>
+#define PCMCIA_IRQ AU1000_GPIO_11
+#endif
+
+static int pb1x00_pcmcia_init(struct pcmcia_init *init)
+{
+#ifdef CONFIG_MIPS_PB1000
+	u16 pcr;
+	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
+
+	au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */
+	au_sync_delay(100);
+	au_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);
+	au_writel(pcr, PB1000_PCR);
+	au_sync_delay(20);
+	  
+	return PCMCIA_NUM_SOCKS;
+
+#else /* fixme -- take care of the Pb1500 at some point */
+
+	u16 pcr;
+	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */
+	pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
+	au_writew(pcr, PB1100_MEM_PCMCIA);
+	au_sync_delay(500);
+	return PCMCIA_NUM_SOCKS;
+#endif
+}
+
+static int pb1x00_pcmcia_shutdown(void)
+{
+#ifdef CONFIG_MIPS_PB1000
+	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);
+	au_writel(pcr, PB1000_PCR);
+	au_sync_delay(20);
+	return 0;
+#else
+	u16 pcr;
+	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */
+	pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
+	au_writew(pcr, PB1100_MEM_PCMCIA);
+	au_sync_delay(2);
+	return 0;
+#endif
+}
+
+static int 
+pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+{
+	u32 inserted0, inserted1;
+	u16 vs0, vs1;
+
+#ifdef CONFIG_MIPS_PB1000
+	vs0 = vs1 = (u16)au_readl(PB1000_ACR1);
+	inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2));
+	inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2));
+	vs0 = (vs0 >> 4) & 0x3;
+	vs1 = (vs1 >> 12) & 0x3;
+#else
+	vs0 = (au_readw(PB1100_BOARD_STATUS) >> 4) & 0x3;
+	inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
+#endif
+
+	state->ready = 0;
+	state->vs_Xv = 0;
+	state->vs_3v = 0;
+	state->detect = 0;
+
+	if (sock == 0) {
+		if (inserted0) {
+			switch (vs0) {
+				case 0:
+				case 2:
+					state->vs_3v=1;
+					break;
+				case 3: /* 5V */
+					break;
+				default:
+					/* return without setting 'detect' */
+					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
+							vs0);
+					return;
+			}
+			state->detect = 1;
+		}
+	}
+	else  {
+		if (inserted1) {
+			switch (vs1) {
+				case 0:
+				case 2:
+					state->vs_3v=1;
+					break;
+				case 3: /* 5V */
+					break;
+				default:
+					/* return without setting 'detect' */
+					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
+							vs1);
+					return;
+			}
+			state->detect = 1;
+		}
+	}
+
+	if (state->detect) {
+		state->ready = 1;
+	}
+
+	state->bvd1=1;
+	state->bvd2=1;
+	state->wrprot=0; 
+	return 1;
+}
+
+
+static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+	if(info->sock > PCMCIA_MAX_SOCK) return -1;
+
+	/*
+	 * Even in the case of the Pb1000, both sockets are connected
+	 * to the same irq line.
+	 */
+	info->irq = PCMCIA_IRQ;
+
+	return 0;
+}
+
+
+static int 
+pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+	u16 pcr;
+
+	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
+
+#ifdef CONFIG_MIPS_PB1000
+	pcr = au_readl(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;
+	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;
+	}
+
+	if (configure->sock == 0) {
+	pcr &= ~(PCR_SLOT_0_RST);
+		if (configure->reset)
+		pcr |= PCR_SLOT_0_RST;
+	}
+	else {
+		pcr &= ~(PCR_SLOT_1_RST);
+		if (configure->reset)
+			pcr |= PCR_SLOT_1_RST;
+	}
+	au_writel(pcr, PB1000_PCR);
+	au_sync_delay(300);
+
+#else
+
+	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf;
+
+	DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x, reset %d\n", 
+			configure->vcc, configure->vpp, pcr, configure->reset);
+
+
+	switch(configure->vcc){
+		case 0:  /* Vcc 0 */
+			pcr |= SET_VCC_VPP(0,0);
+			break;
+		case 50: /* Vcc 5V */
+			switch(configure->vpp) {
+				case 0:
+					pcr |= SET_VCC_VPP(2,0);
+					break;
+				case 50:
+					pcr |= SET_VCC_VPP(2,1);
+					break;
+				case 12:
+					pcr |= SET_VCC_VPP(2,2);
+					break;
+				case 33:
+				default:
+					pcr |= SET_VCC_VPP(0,0);
+					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(1,0);
+					break;
+				case 12:
+					pcr |= SET_VCC_VPP(1,2);
+					break;
+				case 33:
+					pcr |= SET_VCC_VPP(1,1);
+					break;
+				case 50:
+				default:
+					pcr |= SET_VCC_VPP(0,0);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
+							__FUNCTION__, 
+							configure->vcc, 
+							configure->vpp);
+					break;
+			}
+			break;
+		default: /* what's this ? */
+			pcr |= SET_VCC_VPP(0,0);
+			printk(KERN_ERR "%s: bad Vcc %d\n", 
+					__FUNCTION__, configure->vcc);
+			break;
+	}
+
+	au_writew(pcr, PB1100_MEM_PCMCIA);
+	au_sync_delay(300);
+
+	if (!configure->reset) {
+		pcr |= PB1100_PC_DRV_EN;
+		au_writew(pcr, PB1100_MEM_PCMCIA);
+		au_sync_delay(100);
+		pcr |= PB1100_PC_DEASSERT_RST;
+		au_writew(pcr, PB1100_MEM_PCMCIA);
+		au_sync_delay(100);
+	}
+	else {
+		pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
+		au_writew(pcr, PB1100_MEM_PCMCIA);
+		au_sync_delay(100);
+	}
+#endif
+	return 0;
+}
+
+struct pcmcia_low_level pb1x00_pcmcia_ops = { 
+	pb1x00_pcmcia_init,
+	pb1x00_pcmcia_shutdown,
+	pb1x00_pcmcia_socket_state,
+	pb1x00_pcmcia_get_irq_info,
+	pb1x00_pcmcia_configure_socket
+};
diff -urN linux-2.4.20-pre6/drivers/scsi/Config.in linux-2.4.20-pre7/drivers/scsi/Config.in
--- linux-2.4.20-pre6/drivers/scsi/Config.in	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/scsi/Config.in	Thu Sep 12 20:01:45 2002
@@ -36,9 +36,7 @@
    dep_tristate 'SGI WD93C93 SCSI Driver' CONFIG_SGIWD93_SCSI $CONFIG_SCSI
 fi
 if [ "$CONFIG_DECSTATION" = "y" ]; then
-   if [ "$CONFIG_TC" = "y" ]; then
-      dep_tristate 'DEC NCR53C94 Scsi Driver' CONFIG_SCSI_DECNCR $CONFIG_SCSI
-   fi
+   dep_tristate 'DEC NCR53C94 Scsi Driver' CONFIG_SCSI_DECNCR $CONFIG_SCSI $CONFIG_TC
    dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI
 fi
 
diff -urN linux-2.4.20-pre6/drivers/scsi/dec_esp.c linux-2.4.20-pre7/drivers/scsi/dec_esp.c
--- linux-2.4.20-pre6/drivers/scsi/dec_esp.c	Sun Sep  9 10:52:35 2001
+++ linux-2.4.20-pre7/drivers/scsi/dec_esp.c	Thu Sep 12 20:01:45 2002
@@ -46,6 +46,8 @@
 #include <asm/dec/ioasic_ints.h>
 #include <asm/dec/machtype.h>
 
+#include <asm/system.h>
+
 /*
  * Once upon a time the pmaz code used to be working but
  * it hasn't been maintained for quite some time.
@@ -101,6 +103,8 @@
 volatile unsigned long *scsi_sdr0;
 volatile unsigned long *scsi_sdr1;
 
+static void scsi_dma_merr_int(int, void *, struct pt_regs *);
+static void scsi_dma_err_int(int, void *, struct pt_regs *);
 static void scsi_dma_int(int, void *, struct pt_regs *);
 
 static Scsi_Host_Template driver_template = SCSI_DEC_ESP;
@@ -179,7 +183,7 @@
 		/* get virtual dma address for command buffer */
 		esp->esp_command_dvma = (__u32) KSEG1ADDR((volatile unsigned char *) cmd_buffer);
 	
-		esp->irq = SCSI_INT;
+		esp->irq = dec_interrupt[DEC_IRQ_ASC];
 
 		esp->scsi_id = 7;
 		
@@ -189,11 +193,20 @@
 		esp_initialize(esp);
 
 		if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
-				"NCR 53C94 SCSI", NULL))
+				"ncr53c94", NULL))
 			goto err_dealloc;
-		if (request_irq(SCSI_DMA_INT, scsi_dma_int, SA_INTERRUPT, 
-				"JUNKIO SCSI DMA", NULL))
+		if (request_irq(dec_interrupt[DEC_IRQ_ASC_MERR],
+				scsi_dma_merr_int, SA_INTERRUPT, 
+				"ncr53c94 error", NULL))
 			goto err_free_irq;
+		if (request_irq(dec_interrupt[DEC_IRQ_ASC_ERR],
+				scsi_dma_err_int, SA_INTERRUPT, 
+				"ncr53c94 overrun", NULL))
+			goto err_free_irq_merr;
+		if (request_irq(dec_interrupt[DEC_IRQ_ASC_DMA],
+				scsi_dma_int, SA_INTERRUPT, 
+				"ncr53c94 dma", NULL))
+			goto err_free_irq_err;
  			
 	}
 
@@ -271,41 +284,35 @@
 	}
 	return 0;
 
- err_free_irq:
+err_free_irq_err:
+	free_irq(dec_interrupt[DEC_IRQ_ASC_ERR], scsi_dma_err_int);
+err_free_irq_merr:
+	free_irq(dec_interrupt[DEC_IRQ_ASC_MERR], scsi_dma_merr_int);
+err_free_irq:
 	free_irq(esp->irq, esp_intr);
- err_dealloc:
+err_dealloc:
 	esp_deallocate(esp);
 	return 0;
 }
 
 /************************************************************* DMA Functions */
-static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
+static void scsi_dma_merr_int(int irq, void *dev_id, struct pt_regs *regs)
 {
-	extern volatile unsigned int *isr;
-	unsigned int dummy;
+	printk("Got unexpected SCSI DMA Interrupt! < ");
+	printk("SCSI_DMA_MEMRDERR ");
+	printk(">\n");
+}
 
-	if (*isr & SCSI_PTR_LOADED) {
-		/* next page */
-		*scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3;
-		*isr &= ~SCSI_PTR_LOADED;
-	} else {
-		if (*isr & SCSI_PAGOVRRUN)
-			*isr &= ~SCSI_PAGOVRRUN;
-		if (*isr & SCSI_DMA_MEMRDERR) {
-			printk("Got unexpected SCSI DMA Interrupt! < ");
-			printk("SCSI_DMA_MEMRDERR ");
-		printk(">\n");
-			*isr &= ~SCSI_DMA_MEMRDERR;
-		}
-	}
+static void scsi_dma_err_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* empty */
+}
 
-	/*
-	 * This routine will only work on IOASIC machines
-	 * so we can avoid an indirect function call here
-	 * and flush the writeback buffer the fast way
-	 */
-	dummy = *isr;
-	dummy = *isr;
+static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* next page */
+	*scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3;
+	fast_iob();
 }
 
 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
@@ -357,9 +364,6 @@
 
 static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
 {
-	extern volatile unsigned int *isr;
-	unsigned int dummy;
-
 	if (vaddress & 3)
 		panic("dec_efs.c: unable to handle partial word transfers, yet...");
 
@@ -372,19 +376,11 @@
 	/* prepare for next page */
 	*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
 	*ioasic_ssr |= (SCSI_DMA_DIR | SCSI_DMA_EN);
-
-	/*
-	 * see above
-	 */
-	dummy = *isr;
-	dummy = *isr;
+	fast_iob();
 }
 
 static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
 {
-	extern volatile unsigned int *isr;
-	unsigned int dummy;
-
 	if (vaddress & 3)
 		panic("dec_efs.c: unable to handle partial word transfers, yet...");
 
@@ -397,22 +393,17 @@
 	/* prepare for next page */
 	*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
 	*ioasic_ssr |= SCSI_DMA_EN;
-
-	/*
-	 * see above
-	 */
-	dummy = *isr;
-	dummy = *isr;
+	fast_iob();
 }
 
 static void dma_ints_off(struct NCR_ESP *esp)
 {
-	disable_irq(SCSI_DMA_INT);
+	disable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]);
 }
 
 static void dma_ints_on(struct NCR_ESP *esp)
 {
-	enable_irq(SCSI_DMA_INT);
+	enable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]);
 }
 
 static int dma_irq_p(struct NCR_ESP *esp)
@@ -459,12 +450,12 @@
 		sg[sz].dvma_addr = PHYSADDR(sg[sz].addr);
 	sz--;
     }
-	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
+	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dma_address);
 }
 
 static void dma_advance_sg(Scsi_Cmnd * sp)
 {
-	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
+	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dma_address);
 }
 
 static void pmaz_dma_drain(struct NCR_ESP *esp)
@@ -483,6 +474,8 @@
 
 	*dmareg = TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
 
+	iob();
+
 	esp_virt_buffer = vaddress;
 	scsi_current_length = length;
 }
@@ -497,6 +490,7 @@
 	*dmareg = TC_ESP_DMAR_WRITE | 
 		TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
 
+	iob();
 }
 
 static void pmaz_dma_ints_off(struct NCR_ESP *esp)
diff -urN linux-2.4.20-pre6/drivers/scsi/wd33c93.h linux-2.4.20-pre7/drivers/scsi/wd33c93.h
--- linux-2.4.20-pre6/drivers/scsi/wd33c93.h	Thu Oct 25 13:53:51 2001
+++ linux-2.4.20-pre7/drivers/scsi/wd33c93.h	Thu Sep 12 20:01:47 2002
@@ -19,12 +19,9 @@
  * GNU General Public License for more details.
  *
  */
-
 #ifndef WD33C93_H
 #define WD33C93_H
 
-#include <linux/config.h>
-
 #define PROC_INTERFACE     /* add code for /proc/scsi/wd33c93/xxx interface */
 #ifdef  PROC_INTERFACE
 #define PROC_STATISTICS    /* add code for keeping various real time stats */
diff -urN linux-2.4.20-pre6/drivers/sgi/Config.in linux-2.4.20-pre7/drivers/sgi/Config.in
--- linux-2.4.20-pre6/drivers/sgi/Config.in	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/sgi/Config.in	Thu Sep 12 20:01:47 2002
@@ -10,7 +10,7 @@
 fi
 bool 'SGI DS1286  RTC support' CONFIG_SGI_DS1286
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then  
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX
 fi
 
diff -urN linux-2.4.20-pre6/drivers/sgi/char/ds1286.c linux-2.4.20-pre7/drivers/sgi/char/ds1286.c
--- linux-2.4.20-pre6/drivers/sgi/char/ds1286.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/sgi/char/ds1286.c	Thu Sep 12 20:01:47 2002
@@ -1,8 +1,8 @@
 /*
- * DS1286 Real Time Clock interface for Linux	
+ * DS1286 Real Time Clock interface for Linux
  *
  * Copyright (C) 1998, 1999, 2000 Ralf Baechle
- *	
+ *
  * Based on code written by Paul Gortmaker.
  *
  * This driver allows use of the real time clock (built into nearly all
@@ -82,7 +82,7 @@
 unsigned char ds1286_status;		/* bitmapped status byte.	*/
 unsigned long ds1286_freq;		/* Current periodic IRQ rate	*/
 
-unsigned char days_in_mo[] = 
+unsigned char days_in_mo[] =
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 /*
@@ -99,7 +99,7 @@
                         unsigned int cmd, unsigned long arg)
 {
 
-	struct rtc_time wtime; 
+	struct rtc_time wtime;
 
 	switch (cmd) {
 	case RTC_AIE_OFF:	/* Mask alarm int. enab. bit	*/
@@ -175,7 +175,7 @@
 		 */
 
 		ds1286_get_alm_time(&wtime);
-		break; 
+		break;
 	}
 	case RTC_ALM_SET:	/* Store a time into the alarm */
 	{
@@ -229,7 +229,7 @@
 		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
 				   sizeof(struct rtc_time)))
 			return -EFAULT;
-		
+
 		return ds1286_set_time(&rtc_tm);
 	}
 	default:
@@ -396,13 +396,13 @@
 	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
 	 * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
 	 * If you need to know *exactly* when a second has started, enable
-	 * periodic update complete interrupts, (via ioctl) and then 
+	 * periodic update complete interrupts, (via ioctl) and then
 	 * immediately read /dev/rtc which will block until you get the IRQ.
 	 * Once the read clears, read the RTC time (again via ioctl). Easy.
 	 */
diff -urN linux-2.4.20-pre6/drivers/sgi/char/graphics.c linux-2.4.20-pre7/drivers/sgi/char/graphics.c
--- linux-2.4.20-pre6/drivers/sgi/char/graphics.c	Thu Oct 11 09:43:30 2001
+++ linux-2.4.20-pre7/drivers/sgi/char/graphics.c	Thu Sep 12 20:01:47 2002
@@ -95,10 +95,10 @@
 		struct gfx_getboardinfo_args *bia = (void *) arg;
 		void   *dest_buf;
 		int    max_len;
-		
+
 		i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct gfx_getboardinfo_args));
 		if (i) return i;
-		
+
 		if (__get_user (board,    &bia->board) ||
 		    __get_user (dest_buf, &bia->buf) ||
 		    __get_user (max_len,  &bia->len))
@@ -185,7 +185,7 @@
 	default:
 		if (cards [devnum].g_ioctl)
 			return (*cards [devnum].g_ioctl)(devnum, cmd, arg);
-		
+
 	}
 	return -EINVAL;
 }
@@ -210,14 +210,14 @@
 	return 0;
 }
 
-/* 
+/*
  * This is the core of the direct rendering engine.
  */
 struct page *
 sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int
 		     no_share)
 {
-	pgd_t *pgd; pmd_t *pmd; pte_t *pte; 
+	pgd_t *pgd; pmd_t *pmd; pte_t *pte;
 	int board = GRAPHICS_CARD (vma->vm_dentry->d_inode->i_rdev);
 
 	unsigned long virt_add, phys_add;
@@ -226,7 +226,7 @@
 	printk ("Got a page fault for board %d address=%lx guser=%lx\n", board,
 		address, (unsigned long) cards[board].g_user);
 #endif
-	
+
 	/* Figure out if another process has this mapped, and revoke the mapping
 	 * in that case. */
 	if (cards[board].g_user && cards[board].g_user != current) {
@@ -260,7 +260,7 @@
 static struct vm_operations_struct graphics_mmap = {
 	nopage:	sgi_graphics_nopage,	/* our magic no-page fault handler */
 };
-	
+
 int
 sgi_graphics_mmap (struct file *file, struct vm_area_struct *vma)
 {
diff -urN linux-2.4.20-pre6/drivers/sgi/char/graphics.h linux-2.4.20-pre7/drivers/sgi/char/graphics.h
--- linux-2.4.20-pre6/drivers/sgi/char/graphics.h	Fri Jun 25 17:39:34 1999
+++ linux-2.4.20-pre7/drivers/sgi/char/graphics.h	Thu Sep 12 20:01:47 2002
@@ -6,7 +6,7 @@
 
 	/* Last process that got the graphics registers mapped  */
 	struct task_struct *g_user;
-	
+
 	/* Board info */
 	void               *g_board_info;
 	int                g_board_info_len;
diff -urN linux-2.4.20-pre6/drivers/sgi/char/newport.c linux-2.4.20-pre7/drivers/sgi/char/newport.c
--- linux-2.4.20-pre6/drivers/sgi/char/newport.c	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/sgi/char/newport.c	Thu Sep 12 20:01:47 2002
@@ -28,7 +28,7 @@
 #define LOAD(val) x->val = npregs->set.val;
 #define LOADI(val) x->val = npregs->set.val.word;
 #define LOADC(val) x->val = npregs->cset.val;
-	
+
 	LOAD(drawmode1);
 	LOAD(drawmode0);
 	LOAD(lsmode);
@@ -65,9 +65,9 @@
 	LOAD(wrmask);
 	LOAD(hostrw0);
 	LOAD(hostrw1);
-	
+
         /* configregs */
-	
+
 	LOADC(smask1x);
 	LOADC(smask1y);
 	LOADC(smask2x);
@@ -112,7 +112,7 @@
 #define STOREI(val) npregs->set.val.word = x->val
 #define STOREC(val) npregs->cset.val = x->val
 	newport_wait ();
-	
+
 	STORE(drawmode1);
 	STORE(drawmode0);
 	STORE(lsmode);
@@ -149,9 +149,9 @@
 	STORE(wrmask);
 	STORE(hostrw0);
 	STORE(hostrw1);
-	
+
         /* configregs */
-	
+
 	STOREC(smask1x);
 	STOREC(smask1y);
 	STOREC(smask2x);
@@ -174,7 +174,7 @@
 	switch (cmd){
 	case NG1_SETDISPLAYMODE: {
 		struct ng1_setdisplaymode_args request;
-		
+
 		if (copy_from_user (&request, (void *) arg, sizeof (request)))
 			return -EFAULT;
 
@@ -183,8 +183,8 @@
 		npregs->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
 			DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
 		xmap9FIFOWait (npregs);
-		
-		/* FIXME: timing is wrong, just be extracted from 
+
+		/* FIXME: timing is wrong, just be extracted from
 		 * the per-board timing table.  I still have to figure
 		 * out where this comes from
 		 *
@@ -206,13 +206,13 @@
 	}
 	case NG1_SET_CURSOR_HOTSPOT: {
 		struct ng1_set_cursor_hotspot request;
-		
+
 		if (copy_from_user (&request, (void *) arg, sizeof (request)))
 			return -EFAULT;
 		/* FIXME: make request.xhot, request.yhot the hot spot */
 		return 0;
 	}
-	
+
 	case NG1_SETGAMMARAMP0:
 		/* FIXME: load the gamma ramps :-) */
 		return 0;
diff -urN linux-2.4.20-pre6/drivers/sgi/char/rrm.c linux-2.4.20-pre7/drivers/sgi/char/rrm.c
--- linux-2.4.20-pre6/drivers/sgi/char/rrm.c	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/sgi/char/rrm.c	Thu Sep 12 20:01:47 2002
@@ -1,5 +1,5 @@
 /*
- * Linux Rendering Resource Manager 
+ * Linux Rendering Resource Manager
  *
  *          Implements the SGI-compatible rendering resource manager.
  *          This takes care of implementing the virtualized video hardware
@@ -51,7 +51,7 @@
 rrm_command (unsigned int cmd, void *arg)
 {
 	int i, rnid;
-	
+
 	if (cmd > RRM_FUNCTIONS){
 		printk ("Called unimplemented rrm ioctl: %d\n", cmd + RRM_BASE);
 		return -EINVAL;
diff -urN linux-2.4.20-pre6/drivers/sgi/char/sgicons.c linux-2.4.20-pre7/drivers/sgi/char/sgicons.c
--- linux-2.4.20-pre6/drivers/sgi/char/sgicons.c	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/sgi/char/sgicons.c	Thu Sep 12 20:01:47 2002
@@ -4,7 +4,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
  *
- * This implement a virtual console interface.
+ * This implements a virtual console interface.
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -urN linux-2.4.20-pre6/drivers/sgi/char/sgiserial.c linux-2.4.20-pre7/drivers/sgi/char/sgiserial.c
--- linux-2.4.20-pre6/drivers/sgi/char/sgiserial.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/sgi/char/sgiserial.c	Thu Sep 12 20:01:47 2002
@@ -104,7 +104,7 @@
 /* serial subtype definitions */
 #define SERIAL_TYPE_NORMAL	1
 #define SERIAL_TYPE_CALLOUT	2
-  
+
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 256
 
@@ -170,7 +170,7 @@
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 	9600, 19200, 38400, 57600, 115200, 0 };
 
-/* 
+/*
  * Reading and writing Zilog8530 registers.  The delays are to make this
  * driver work on the Sun4 which needs a settling delay after each chip
  * register access, other machines handle this in hardware via auxiliary
@@ -295,7 +295,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 	save_flags(flags); cli();
 	if (info->curregs[5] & TxENAB) {
 		info->curregs[5] &= ~TxENAB;
@@ -309,10 +309,10 @@
 {
 	struct sgi_serial *info = (struct sgi_serial *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_start"))
 		return;
-	
+
 	save_flags(flags); cli();
 	if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) {
 		info->curregs[5] |= TxENAB;
@@ -374,7 +374,7 @@
  * 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.
@@ -632,7 +632,7 @@
 {
 	struct sgi_serial	*info = (struct sgi_serial *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -652,13 +652,13 @@
  *
  * 	serial interrupt routine -> (scheduler tqueue) ->
  * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
- * 
+ *
  */
 static void do_serial_hangup(void *private_)
 {
 	struct sgi_serial	*info = (struct sgi_serial *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -724,7 +724,7 @@
 	write_zsreg(info->zs_channel, 3, info->curregs[3]);
 	write_zsreg(info->zs_channel, 5, info->curregs[5]);
 	write_zsreg(info->zs_channel, 9, info->curregs[9]);
-	
+
 	/*
 	 * And clear the interrupt registers again for luck.
 	 */
@@ -764,9 +764,9 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       info->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
-	
+
 	if (info->xmit_buf) {
 		free_page((unsigned long) info->xmit_buf);
 		info->xmit_buf = 0;
@@ -774,7 +774,7 @@
 
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
-	
+
 	info->flags &= ~ZILOG_INITIALIZED;
 	restore_flags(flags);
 }
@@ -901,7 +901,7 @@
 	restore_flags(flags);
 }
 
-/* 
+/*
  * This is the more generic put_char function for the driver.
  * In earlier versions of this driver, "rs_put_char" was the
  * name of the console-specific fucntion, now called zs_cons_put_char
@@ -909,7 +909,7 @@
 
 static void rs_put_char(struct tty_struct *tty, char ch)
 {
-	struct sgi_zschannel *chan = 
+	struct sgi_zschannel *chan =
 		((struct sgi_serial *)tty->driver_data)->zs_channel;
 	volatile unsigned char junk;
 	int flags, loops = 0;
@@ -1014,7 +1014,7 @@
 
 	save_flags(flags);
 	while (1) {
-		cli();		
+		cli();
 		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				   SERIAL_XMIT_SIZE - info->xmit_head));
 		if (c <= 0)
@@ -1078,7 +1078,7 @@
 {
 	struct sgi_serial *info = (struct sgi_serial *)tty->driver_data;
 	int	ret;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
 		return 0;
 	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
@@ -1090,7 +1090,7 @@
 static int rs_chars_in_buffer(struct tty_struct *tty)
 {
 	struct sgi_serial *info = (struct sgi_serial *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
 		return 0;
 	return info->xmit_cnt;
@@ -1099,7 +1099,7 @@
 static void rs_flush_buffer(struct tty_struct *tty)
 {
 	struct sgi_serial *info = (struct sgi_serial *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
 	cli();
@@ -1155,7 +1155,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1165,14 +1165,14 @@
 	struct sgi_serial *info = (struct sgi_serial *)tty->driver_data;
 #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))
 		info->x_char = STOP_CHAR(tty);
 
@@ -1189,14 +1189,14 @@
 	struct sgi_serial *info = (struct sgi_serial *)tty->driver_data;
 #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;
@@ -1222,7 +1222,7 @@
 			   struct serial_struct * retinfo)
 {
 	struct serial_struct tmp;
-  
+
 	if (!retinfo)
 		return -EFAULT;
 	memset(&tmp, 0, sizeof(tmp));
@@ -1291,7 +1291,7 @@
  * 	    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. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct sgi_serial * info, unsigned int *value)
 {
@@ -1304,7 +1304,7 @@
 	junk = ioc_icontrol->istat0;
 	sti();
 	return put_user(status,value);
-} 
+}
 
 static int get_modem_info(struct sgi_serial * info, unsigned int *value)
 {
@@ -1333,7 +1333,7 @@
 	if (get_user(arg, value))
 		return -EFAULT;
 	switch (cmd) {
-	case TIOCMBIS: 
+	case TIOCMBIS:
 		if (arg & TIOCM_RTS)
 			info->curregs[5] |= RTS;
 		if (arg & TIOCM_DTR)
@@ -1389,7 +1389,7 @@
 		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);
@@ -1438,7 +1438,7 @@
 				    info, sizeof(struct sgi_serial)))
 				return -EFAULT;
 			return 0;
-			
+
 		default:
 			return -ENOIOCTLCMD;
 		}
@@ -1464,7 +1464,7 @@
 /*
  * ------------------------------------------------------------
  * 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
  * ZILOG structure from the interrupt chain if necessary, and we free
@@ -1478,14 +1478,14 @@
 
 	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
 		return;
-	
+
 	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, info->count);
 #endif
@@ -1520,7 +1520,7 @@
 	if (info->flags & ZILOG_CALLOUT_ACTIVE)
 		info->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1576,10 +1576,10 @@
 void rs_hangup(struct tty_struct *tty)
 {
 	struct sgi_serial * info = (struct sgi_serial *)tty->driver_data;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
 		return;
-	
+
 	rs_flush_buffer(tty);
 	shutdown(info);
 	info->event = 0;
@@ -1635,7 +1635,7 @@
 		info->flags |= ZILOG_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.
@@ -1655,7 +1655,7 @@
 		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
@@ -1683,7 +1683,7 @@
 			if (info->flags & ZILOG_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -1715,7 +1715,7 @@
 		return retval;
 	info->flags |= ZILOG_NORMAL_ACTIVE;
 	return 0;
-}	
+}
 
 /*
  * This routine is called whenever a serial port is opened.  It
@@ -1767,17 +1767,17 @@
 	if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->normal_termios;
-		else 
+		else
 			*tty->termios = info->callout_termios;
 		change_speed(info);
 	}
 
-	/* If this is the serial console change the speed to 
+	/* If this is the serial console change the speed to
 	 * the right value
 	 */
 	if (info->is_cons) {
 		info->tty->termios->c_cflag = sgisercon->cflag;
-		change_speed(info);		
+		change_speed(info);
 	}
 
 	info->session = current->session;
@@ -1868,7 +1868,7 @@
 
 	/* Initialize the tty_driver structure */
 	/* SGI: Not all of this is exactly right for us. */
-	
+
 	memset(&serial_driver, 0, sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
 #ifdef CONFIG_DEVFS_FS
@@ -1923,7 +1923,7 @@
 		panic("Couldn't register serial driver");
 	if (tty_register_driver(&callout_driver))
 		panic("Couldn't register callout driver");
-	
+
 	save_flags(flags); cli();
 
 	/* Set up our interrupt linked list */
@@ -2014,7 +2014,7 @@
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
-		printk("tty%02d at 0x%04x (irq = %d)", info->line, 
+		printk("tty%02d at 0x%04x (irq = %d)", info->line,
 		       info->port, info->irq);
 		printk(" is a Zilog8530\n");
 	}
@@ -2052,7 +2052,7 @@
 rs_cons_hook(int chip, int out, int line)
 {
 	int channel;
-	
+
 	if(chip)
 		panic("rs_cons_hook called with chip not zero");
 	if(line != 0 && line != 1)
@@ -2068,11 +2068,11 @@
 	zs_soft[channel].change_needed = 0;
 	zs_soft[channel].clk_divisor = 16;
 	zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
-	if(out) 
+	if(out)
 		zs_cons_chanout = ((chip * 2) + channel);
-	else 
+	else
 		zs_cons_chanin = ((chip * 2) + channel);
-	
+
 	rs_cons_check(&zs_soft[channel], channel);
 }
 
@@ -2136,7 +2136,7 @@
 	int	cflag = CREAD | HUPCL | CLOCAL;
 	char	*s, *dbaud;
 	int     i, brg;
-    
+
 	if (options) {
 		baud = simple_strtoul(options, NULL, 10);
 		s = options;
@@ -2213,8 +2213,8 @@
         rs_cons_hook(0, 0, con->index);
 	info = zs_soft + con->index;
 	info->is_cons = 1;
-    
-	printk("Console: ttyS%d (Zilog8530), %d baud\n", 
+
+	printk("Console: ttyS%d (Zilog8530), %d baud\n",
 						info->line, baud);
 
 	i = con->cflag & CBAUD;
@@ -2254,14 +2254,14 @@
 		zscons_regs[4] |= SB2;
 	else
 		zscons_regs[4] |= SB1;
-	
+
 	sgisercon = con;
 
 	brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor);
 	zscons_regs[12] = brg & 0xff;
 	zscons_regs[13] = (brg >> 8) & 0xff;
 	memcpy(info->curregs, zscons_regs, sizeof(zscons_regs));
-	memcpy(info->pendregs, zscons_regs, sizeof(zscons_regs));    
+	memcpy(info->pendregs, zscons_regs, sizeof(zscons_regs));
 	load_zsregs(info->zs_channel, zscons_regs);
 	ZS_CLEARERR(info->zs_channel);
 	ZS_CLEARFIFO(info->zs_channel);
diff -urN linux-2.4.20-pre6/drivers/sgi/char/sgiserial.h linux-2.4.20-pre7/drivers/sgi/char/sgiserial.h
--- linux-2.4.20-pre6/drivers/sgi/char/sgiserial.h	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/sgi/char/sgiserial.h	Thu Sep 12 20:01:47 2002
@@ -57,7 +57,7 @@
 /*
  * Definitions for ZILOG_struct (and serial_struct) flags field
  */
-#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes
 				   on the callout port */
 #define ZILOG_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
 #define ZILOG_SAK	0x0004	/* Secure Attention Key (Orange book) */
@@ -93,7 +93,7 @@
 #ifdef __KERNEL__
 /*
  * This is our internal structure for each serial port's state.
- * 
+ *
  * Many fields are paralleled by the structure used by the serial_struct
  * structure.
  *
diff -urN linux-2.4.20-pre6/drivers/sgi/char/shmiq.c linux-2.4.20-pre7/drivers/sgi/char/shmiq.c
--- linux-2.4.20-pre6/drivers/sgi/char/shmiq.c	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/sgi/char/shmiq.c	Thu Sep 12 20:01:47 2002
@@ -10,7 +10,7 @@
  * any other number implements /dev/qcntl${minor-1}
  *
  * /dev/shmiq is used by the X server for two things:
- * 
+ *
  *    1. for I_LINK()ing trough ioctl the file handle of a
  *       STREAMS device.
  *
@@ -36,7 +36,7 @@
  * need an strace from an X server that runs on a machine with more
  * than one keyboard.  And this is a problem since the file handles
  * are pushed in /dev/shmiq, while the events should be dispatched to
- * the /dev/qcntlN device. 
+ * the /dev/qcntlN device.
  *
  * Until then, I just allow for 1 qcntl device.
  *
@@ -84,7 +84,7 @@
 	int    tail;		/* our copy of the shmiq->tail */
 	int    events;
 	int    mapped;
-	
+
 	wait_queue_head_t    proc_list;
 	struct fasync_struct *fasync;
 } shmiqs [MAX_SHMI_QUEUES];
@@ -106,12 +106,12 @@
 		return;
 	}
 	tail_next = (s->tail + 1) % (shmiqs [device].events);
-	
+
 	if (tail_next == s->head){
 		s->flags |= SHMIQ_OVERFLOW;
 		return;
 	}
-	
+
 	e->un.time = jiffies;
 	s->events [s->tail] = *e;
 	printk ("KERNEL: dev=%d which=%d type=%d flags=%d\n",
@@ -151,7 +151,7 @@
 
 	if (fdes > MAX_SHMIQ_DEVS)
 		return -EINVAL;
-	
+
 	if (!shmiq_pushed_devices [fdes].used)
 		return -EINVAL;
 
@@ -179,7 +179,7 @@
 
 	case QIOCIISTR: {
 		struct muxioctl *mux = (struct muxioctl *) s->ic_dp;
-		
+
 		printk ("Double indirect ioctl: [%d, %x\n", mux->index, mux->realcmd);
 		return -EINVAL;
 	}
@@ -225,12 +225,12 @@
 	case I_UNLINK:
 		v = shmiq_forget_file (arg);
 		return v;
-		
+
 	case I_STR:
 		v = get_sioc (&sioc, arg);
 		if (v)
 			return v;
-		
+
 		/* FIXME: This forces device = 0 */
 		return shmiq_sioc (0, sioc.ic_cmd, &sioc);
 	}
@@ -249,7 +249,7 @@
 	struct shmiqreq req;
 	struct vm_area_struct *vma;
 	int v;
-	
+
 	switch (cmd) {
 		/*
 		 * The address space is already mapped as a /dev/zero
@@ -259,7 +259,7 @@
 		case QIOCATTACH: {
 			unsigned long vaddr;
 			int s;
-	
+
 			v = verify_area (VERIFY_READ, (void *) arg,
 			                 sizeof (struct shmiqreq));
 			if (v)
@@ -318,7 +318,7 @@
 	int           minor = MINOR (file->f_dentry->d_inode->i_rdev), error;
 	unsigned int  size;
 	unsigned long mem, start;
-	
+
 	/* mmap is only supported on the qcntl devices */
 	if (minor-- == 0)
 		return -EINVAL;
@@ -327,7 +327,7 @@
 		return -EINVAL;
 
 	size  = vma->vm_end - vma->vm_start;
-	start = vma->vm_start; 
+	start = vma->vm_start;
 	lock_kernel();
 	mem = (unsigned long) shmiqs [minor].shmiq_vaddr =  vmalloc_uncached (size);
 	if (!mem) {
@@ -338,7 +338,7 @@
 	/* Prevent the swapper from considering these pages for swap and touching them */
 	vma->vm_flags    |= (VM_SHM  | VM_LOCKED | VM_IO);
 	vma->vm_ops = &qcntl_mmap;
-	
+
 	/* Uncache the pages */
 	vma->vm_page_prot = PAGE_USERIO;
 
@@ -348,7 +348,7 @@
 	/* Init the shared memory input queue */
 	memset (shmiqs [minor].shmiq_vaddr, 0, size);
 	unlock_kernel();
-	
+
 	return error;
 }
 
@@ -374,7 +374,7 @@
 
 	if (!shmiqs [minor].mapped)
 		return 0;
-	
+
 	poll_wait (filp, &shmiqs [minor].proc_list, wait);
 	s = shmiqs [minor].shmiq_vaddr;
 	if (s->head != s->tail)
@@ -421,7 +421,7 @@
 {
 	int minor = MINOR (inode->i_rdev);
 	int j;
-	
+
 	if (minor-- == 0){
 		for (j = 0; j < MAX_SHMIQ_DEVS; j++)
 			shmiq_forget_file (j);
diff -urN linux-2.4.20-pre6/drivers/sgi/char/streamable.c linux-2.4.20-pre7/drivers/sgi/char/streamable.c
--- linux-2.4.20-pre6/drivers/sgi/char/streamable.c	Wed Jul 12 21:58:43 2000
+++ linux-2.4.20-pre7/drivers/sgi/char/streamable.c	Thu Sep 12 20:01:47 2002
@@ -36,13 +36,13 @@
 get_sioc (struct strioctl *sioc, unsigned long arg)
 {
 	int v;
-	
+
 	v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl));
 	if (v)
 		return v;
 	if (copy_from_user (sioc, (void *) arg, sizeof (struct strioctl)))
 		return -EFAULT;
-		
+
 	v = verify_area (VERIFY_WRITE, (void *) sioc->ic_dp, sioc->ic_len);
 	if (v)
 		return v;
@@ -61,7 +61,7 @@
 struct file_operations sgi_gfx_fops = {
 	ioctl:		sgi_gfx_ioctl,
 };
- 
+
 static struct miscdevice dev_gfx = {
 	SGI_GFX_MINOR, "sgi-gfx", &sgi_gfx_fops
 };
@@ -83,12 +83,12 @@
 sgi_kbd_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
 {
 	*found = 1;
-	
+
 	switch (cmd){
 
 	case IDEVINITDEVICE:
 		return 0;
-			
+
 	case IDEVGETDEVICEDESC:
 		if (size >= sizeof (idevDesc)){
 			if (copy_to_user (data, &sgi_kbd_desc, sizeof (sgi_kbd_desc)))
@@ -114,7 +114,7 @@
 {
 	struct strioctl sioc;
 	int    f, v;
-	
+
 	/* IRIX calls I_PUSH on the opened device, go figure */
 	if (cmd == I_PUSH)
 		return 0;
@@ -129,16 +129,16 @@
 		 * call a stock IRIX xxx_wioctl routine
 		 *
 		 * The NULL is supposed to be a idevInfo, right now we
-		 * do not support this in our kernel.  
+		 * do not support this in our kernel.
 		 */
 		return sgi_kbd_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f);
 	}
-	
+
 	if (cmd == SHMIQ_ON){
 		kbd_assigned_device = arg;
 		forward_chars = fg_console + 1;
 		kbd_prev_mode = kbd_table [fg_console].kbdmode;
-		
+
 	        kbd_table [fg_console].kbdmode = VC_RAW;
 	} else if (cmd == SHMIQ_OFF && forward_chars){
 		kbd_table [forward_chars-1].kbdmode = kbd_prev_mode;
@@ -203,15 +203,15 @@
 
 static int mouse_opened;
 static idevValuatorDesc mouse_valuators [MOUSE_VALUATORS];
-	
+
 int
 sgi_mouse_open (struct inode *inode, struct file *file)
 {
 	int i;
-	
+
 	if (mouse_opened)
 		return -EBUSY;
-	
+
 	mouse_opened = 1;
 	for (i = 0; i < MOUSE_VALUATORS; i++)
 		mouse_valuators [i] = mouse_default_valuator;
@@ -235,7 +235,7 @@
 	switch (cmd){
 	case IDEVINITDEVICE:
 		return 0;
-			
+
 	case IDEVGETDEVICEDESC:
 		if (size >= sizeof (idevDesc)){
 			if (copy_to_user (data, &sgi_mouse_desc, sizeof (sgi_mouse_desc)))
@@ -246,7 +246,7 @@
 
 	case IDEVGETVALUATORDESC: {
 		idevGetSetValDesc request, *ureq = (idevGetSetValDesc *) data;
-		
+
 		if (size < sizeof (idevGetSetValDesc))
 			return -EINVAL;
 
@@ -254,7 +254,7 @@
 			return -EFAULT;
 		if (request.valNum >= MOUSE_VALUATORS)
 			return -EINVAL;
-		if (copy_to_user ((void *)&ureq->desc, 
+		if (copy_to_user ((void *)&ureq->desc,
 				  (void *)&mouse_valuators [request.valNum],
 				  sizeof (idevValuatorDesc)))
 			return -EFAULT;
@@ -280,16 +280,16 @@
 		v = get_sioc (&sioc, arg);
 		if (v)
 			return v;
-		
+
 		/* Why like this?  Because this is a sample piece of code
 		 * that can be copied into other drivers and shows how to
 		 * call a stock IRIX xxx_wioctl routine
 		 *
 		 * The NULL is supposed to be a idevInfo, right now we
-		 * do not support this in our kernel.  
+		 * do not support this in our kernel.
 		 */
 		return sgi_mouse_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f);
-		
+
 	case SHMIQ_ON:
 	case SHMIQ_OFF:
 		return 0;
@@ -313,7 +313,7 @@
 {
 	printk ("streamable misc devices registered (keyb:%d, gfx:%d)\n",
 		SGI_STREAMS_KEYBOARD, SGI_GFX_MINOR);
-	
+
 	misc_register (&dev_gfx);
 	misc_register (&dev_input_keyboard);
 	misc_register (&dev_input_mouse);
diff -urN linux-2.4.20-pre6/drivers/sgi/char/usema.c linux-2.4.20-pre7/drivers/sgi/char/usema.c
--- linux-2.4.20-pre6/drivers/sgi/char/usema.c	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/sgi/char/usema.c	Thu Sep 12 20:01:47 2002
@@ -18,7 +18,7 @@
  *
  * For more information:
  * usema(7m), usinit(3p), usnewsema(3p)
- * /usr/include/sys/usioctl.h 
+ * /usr/include/sys/usioctl.h
  *
  */
 #include <linux/fs.h>
@@ -52,7 +52,7 @@
 	newfd = get_unused_fd();
 	if (newfd < 0)
 		return newfd;
-	
+
 	get_file(usema->filp);
 	fd_install(newfd, usema->filp);
 	/* Is that it? */
@@ -66,7 +66,7 @@
 {
 	struct irix_usema *usema = file->private_data;
 	int retval;
-	
+
 	printk("[%s:%d] wants ioctl 0x%xd (arg 0x%lx)",
 	       current->comm, current->pid, cmd, arg);
 
@@ -140,10 +140,10 @@
 sgi_usemaclone_poll(struct file *filp, poll_table *wait)
 {
 	struct irix_usema *usema = filp->private_data;
-	
+
 	printk("[%s:%d] wants to poll usema %p",
 	       current->comm, current->pid, usema);
-	
+
 	return 0;
 }
 
@@ -155,7 +155,7 @@
 	usema = kmalloc (sizeof (struct irix_usema), GFP_KERNEL);
 	if (!usema)
 		return -ENOMEM;
-	
+
 	usema->filp        = filp;
 	init_waitqueue_head(&usema->proc_list);
 	filp->private_data = usema;
diff -urN linux-2.4.20-pre6/drivers/sgi/char/usema.h linux-2.4.20-pre7/drivers/sgi/char/usema.h
--- linux-2.4.20-pre6/drivers/sgi/char/usema.h	Fri Jun 25 17:39:35 1999
+++ linux-2.4.20-pre7/drivers/sgi/char/usema.h	Thu Sep 12 20:01:47 2002
@@ -5,6 +5,6 @@
 #ifndef _SGI_USEMA_H
 #define _SGI_USEMA_H
 
-void usema_init (void); 
+void usema_init (void);
 
 #endif
diff -urN linux-2.4.20-pre6/drivers/sound/au1000.c linux-2.4.20-pre7/drivers/sound/au1000.c
--- linux-2.4.20-pre6/drivers/sound/au1000.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/sound/au1000.c	Thu Sep 12 20:01:47 2002
@@ -42,6 +42,13 @@
  *
  *  Revision history
  *    06.27.2001  Initial version
+ *    03.20.2002  Added mutex locks around read/write methods, to prevent
+ *                simultaneous access on SMP or preemptible kernels. Also
+ *                removed the counter/pointer fragment aligning at the end
+ *                of read/write methods [stevel].
+ *    03.21.2002  Add support for coherent DMA on the audio read/write DMA
+ *                channels [stevel].
+ *
  */
 #include <linux/version.h>
 #include <linux/module.h>
@@ -73,6 +80,7 @@
 #define AU1000_DEBUG
 #undef AU1000_VERBOSE_DEBUG
 
+#define USE_COHERENT_DMA
 
 #define AU1000_MODULE_NAME "Au1000 audio"
 #define PFX AU1000_MODULE_NAME
@@ -110,18 +118,18 @@
 #endif				/* AU1000_DEBUG */
 
 	struct ac97_codec codec;
-	unsigned        codec_base_caps;	// AC'97 reg 00h, "Reset Register"
+	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;
+	struct semaphore 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
@@ -136,7 +144,7 @@
 		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
+		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
@@ -185,6 +193,34 @@
 }
 
 
+#ifdef USE_COHERENT_DMA
+static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle)
+{
+	void* ret = (void *)__get_free_pages(GFP_ATOMIC | GFP_DMA,
+					     get_order(size));
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_phys(ret);
+	}
+	return ret;
+}
+
+static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)va, get_order(size));
+}
+#else
+static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle)
+{
+	return pci_alloc_consistent(NULL, size, dma_handle);
+}
+
+static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle)
+{
+	pci_free_consistent(NULL, size, va, dma_handle);
+}
+#endif
+
 /* --------------------------------------------------------------------- */
 
 static void au1000_delay(int msec)
@@ -304,6 +340,7 @@
 
 /* --------------------------------------------------------------------- */
 
+/* stop the ADC before calling */
 static void set_adc_rate(struct au1000_state *s, unsigned rate)
 {
 	struct dmabuf  *adc = &s->dma_adc;
@@ -348,6 +385,7 @@
 	dac->sample_rate = dac_rate;
 }
 
+/* stop the DAC before calling */
 static void set_dac_rate(struct au1000_state *s, unsigned rate)
 {
 	struct dmabuf  *dac = &s->dma_dac;
@@ -483,17 +521,20 @@
 
 	set_xmit_slots(db->num_channels);
 
-	set_dma_count(db->dmanr, db->dma_fragsize>>1);
+	init_dma(db->dmanr);
 	if (get_dma_active_buffer(db->dmanr) == 0) {
+		clear_dma_done0(db->dmanr);	// clear DMA done bit
 		set_dma_addr0(db->dmanr, buf1);
 		set_dma_addr1(db->dmanr, buf2);
 	} else {
+		clear_dma_done1(db->dmanr);	// clear DMA done bit
 		set_dma_addr1(db->dmanr, buf1);
 		set_dma_addr0(db->dmanr, buf2);
 	}
+	set_dma_count(db->dmanr, db->dma_fragsize>>1);
 	enable_dma_buffers(db->dmanr);
 
-	enable_dma(db->dmanr);
+	start_dma(db->dmanr);
 
 #ifdef AU1000_VERBOSE_DEBUG
 	dump_au1000_dma_channel(db->dmanr);
@@ -525,17 +566,20 @@
 
 	set_recv_slots(db->num_channels);
 
-	set_dma_count(db->dmanr, db->dma_fragsize>>1);
+	init_dma(db->dmanr);
 	if (get_dma_active_buffer(db->dmanr) == 0) {
+		clear_dma_done0(db->dmanr);	// clear DMA done bit
 		set_dma_addr0(db->dmanr, buf1);
 		set_dma_addr1(db->dmanr, buf2);
 	} else {
+		clear_dma_done1(db->dmanr);	// clear DMA done bit
 		set_dma_addr1(db->dmanr, buf1);
 		set_dma_addr0(db->dmanr, buf2);
 	}
+	set_dma_count(db->dmanr, db->dma_fragsize>>1);
 	enable_dma_buffers(db->dmanr);
 
-	enable_dma(db->dmanr);
+	start_dma(db->dmanr);
 
 #ifdef AU1000_VERBOSE_DEBUG
 	dump_au1000_dma_channel(db->dmanr);
@@ -561,8 +605,7 @@
 				    (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);
+		dma_free(PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
 	}
 	db->rawbuf = db->nextIn = db->nextOut = NULL;
 	db->mapped = db->ready = 0;
@@ -580,9 +623,7 @@
 		db->ready = db->mapped = 0;
 		for (order = DMABUF_DEFAULTORDER;
 		     order >= DMABUF_MINORDER; order--)
-			if ((db->rawbuf =
-			     pci_alloc_consistent(NULL,
-						  PAGE_SIZE << order,
+			if ((db->rawbuf = dma_alloc(PAGE_SIZE << order,
 						  &db->dmaaddr)))
 				break;
 		if (!db->rawbuf)
@@ -686,6 +727,8 @@
 		return;
 	}
 
+	spin_lock(&s->lock);
+	
 	if (buff_done != (DMA_D0 | DMA_D1)) {
 		dac->nextOut += dac->dma_fragsize;
 		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
@@ -699,9 +742,16 @@
 		dac->count -= dac->dma_fragsize;
 		dac->total_bytes += dac->dma_fragsize;
 
-		if (dac->count <= 0)
+		if (dac->count <= 0) {
+#ifdef AU1000_VERBOSE_DEBUG
+			dbg("dac underrun");
+#endif
+			spin_unlock(&s->lock);
 			stop_dac(s);
-		else if (buff_done == DMA_D0) {
+			spin_lock(&s->lock);
+			dac->count = 0;
+			dac->nextIn = dac->nextOut;
+		} 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);
@@ -714,7 +764,9 @@
 		}
 	} else {
 		// both done bits set, we missed an interrupt
+		spin_unlock(&s->lock);
 		stop_dac(s);
+		spin_lock(&s->lock);
 
 		dac->nextOut += 2*dac->dma_fragsize;
 		if (dac->nextOut >= dac->rawbuf + dac->dmasize)
@@ -723,14 +775,18 @@
 		dac->count -= 2*dac->dma_fragsize;
 		dac->total_bytes += 2*dac->dma_fragsize;
 
-		if (dac->count > 0)
+		if (dac->count > 0) {
+			spin_unlock(&s->lock);
 			start_dac(s);
+			spin_lock(&s->lock);
+		}
 	}
 
-
 	/* wake up anybody listening */
 	if (waitqueue_active(&dac->wait))
-		wake_up_interruptible(&dac->wait);
+		wake_up(&dac->wait);
+
+	spin_unlock(&s->lock);
 }
 
 
@@ -752,9 +808,12 @@
 		return;
 	}
 
+	spin_lock(&s->lock);
+	
 	if (buff_done != (DMA_D0 | DMA_D1)) {
 		if (adc->count + adc->dma_fragsize > adc->dmasize) {
 			// Overrun. Stop ADC and log the error
+			spin_unlock(&s->lock);
 			stop_adc(s);
 			adc->error++;
 			err("adc overrun");
@@ -786,12 +845,15 @@
 		}
 	} else {
 		// both done bits set, we missed an interrupt
+		spin_unlock(&s->lock);
 		stop_adc(s);
+		spin_lock(&s->lock);
 		
 		if (adc->count + 2*adc->dma_fragsize > adc->dmasize) {
 			// Overrun. Log the error
 			adc->error++;
 			err("adc overrun");
+			spin_unlock(&s->lock);
 			return;
 		}
 
@@ -802,12 +864,16 @@
 		adc->count += 2*adc->dma_fragsize;
 		adc->total_bytes += 2*adc->dma_fragsize;
 		
+		spin_unlock(&s->lock);
 		start_adc(s);
+		spin_lock(&s->lock);
 	}
 
 	/* wake up anybody listening */
 	if (waitqueue_active(&adc->wait))
-		wake_up_interruptible(&adc->wait);
+		wake_up(&adc->wait);
+
+	spin_unlock(&s->lock);
 }
 
 /* --------------------------------------------------------------------- */
@@ -924,7 +990,7 @@
 	for (sample = 0; sample < num_samples; sample++) {
 		if (copy_from_user(usersample, userbuf,
 				   db->user_bytes_per_sample)) {
-			dbg(__FUNCTION__ "fault");
+			dbg(__FUNCTION__ ": fault");
 			return -EFAULT;
 		}
 
@@ -988,7 +1054,7 @@
 
 		if (copy_to_user(userbuf, usersample,
 				 db->user_bytes_per_sample)) {
-			dbg(__FUNCTION__ "fault");
+			dbg(__FUNCTION__ ": fault");
 			return -EFAULT;
 		}
 
@@ -1050,9 +1116,10 @@
 {
 	struct au1000_state *s = (struct au1000_state *)file->private_data;
 	struct dmabuf  *db = &s->dma_adc;
+	DECLARE_WAITQUEUE(wait, current);
 	ssize_t         ret;
 	unsigned long   flags;
-	int             cnt, remainder, usercnt, avail;
+	int             cnt, usercnt, avail;
 
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
@@ -1064,6 +1131,9 @@
 
 	count *= db->cnt_factor;
 
+	down(&s->sem);
+	add_wait_queue(&db->wait, &wait);
+
 	while (count > 0) {
 		// wait for samples in ADC dma buffer
 		do {
@@ -1071,19 +1141,23 @@
 				start_adc(s);
 			spin_lock_irqsave(&s->lock, flags);
 			avail = db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
 			spin_unlock_irqrestore(&s->lock, flags);
 			if (avail <= 0) {
 				if (file->f_flags & O_NONBLOCK) {
 					if (!ret)
 						ret = -EAGAIN;
-					return ret;
+					goto out;
 				}
-				interruptible_sleep_on(&db->wait);
+				up(&s->sem);
+				schedule();
 				if (signal_pending(current)) {
 					if (!ret)
 						ret = -ERESTARTSYS;
-					return ret;
+					goto out2;
 				}
+				down(&s->sem);
 			}
 		} while (avail <= 0);
 
@@ -1093,16 +1167,15 @@
 					    avail : count, 1)) < 0) {
 			if (!ret)
 				ret = -EFAULT;
-			return ret;
+			goto out;
 		}
 
 		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;
+		spin_unlock_irqrestore(&s->lock, flags);
 
 		count -= cnt;
 		usercnt = cnt / db->cnt_factor;
@@ -1110,25 +1183,11 @@
 		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);
-
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
 	return ret;
 }
 
@@ -1137,9 +1196,14 @@
 {
 	struct au1000_state *s = (struct au1000_state *)file->private_data;
 	struct dmabuf  *db = &s->dma_dac;
+	DECLARE_WAITQUEUE(wait, current);
 	ssize_t         ret = 0;
 	unsigned long   flags;
-	int             cnt, remainder, usercnt, avail;
+	int             cnt, usercnt, avail;
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg("write: count=%d", count);
+#endif
 
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
@@ -1150,45 +1214,51 @@
 
 	count *= db->cnt_factor;
 
+	down(&s->sem);	
+	add_wait_queue(&db->wait, &wait);
+
 	while (count > 0) {
 		// wait for space in playback buffer
 		do {
 			spin_lock_irqsave(&s->lock, flags);
 			avail = (int) db->dmasize - db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
 			spin_unlock_irqrestore(&s->lock, flags);
 			if (avail <= 0) {
 				if (file->f_flags & O_NONBLOCK) {
 					if (!ret)
 						ret = -EAGAIN;
-					return ret;
+					goto out;
 				}
-				interruptible_sleep_on(&db->wait);
+				up(&s->sem);
+				schedule();
 				if (signal_pending(current)) {
 					if (!ret)
 						ret = -ERESTARTSYS;
-					return ret;
+					goto out2;
 				}
+				down(&s->sem);
 			}
 		} while (avail <= 0);
 
-		// copy to nextIn
+		// copy from user to nextIn
 		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
 					    count > avail ?
 					    avail : count, 0)) < 0) {
 			if (!ret)
 				ret = -EFAULT;
-			return ret;
+			goto out;
 		}
 
 		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;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (db->stopped)
+			start_dac(s);
 
 		count -= cnt;
 		usercnt = cnt / db->cnt_factor;
@@ -1196,27 +1266,11 @@
 		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);
-
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
 	return ret;
 }
 
@@ -1241,6 +1295,7 @@
 	}
 
 	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;
@@ -1265,35 +1320,40 @@
 	struct au1000_state *s = (struct au1000_state *)file->private_data;
 	struct dmabuf  *db;
 	unsigned long   size;
+	int ret = 0;
 
 	dbg(__FUNCTION__);
     
 	lock_kernel();
+	down(&s->sem);
 	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;
+		ret = -EINVAL;
+		goto out;
 	}
 	if (vma->vm_pgoff != 0) {
-		unlock_kernel();
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	size = vma->vm_end - vma->vm_start;
 	if (size > (PAGE_SIZE << db->buforder)) {
-		unlock_kernel();
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
 			     size, vma->vm_page_prot)) {
-		unlock_kernel();
-		return -EAGAIN;
+		ret = -EAGAIN;
+		goto out;
 	}
+	vma->vm_flags &= ~VM_IO;
 	db->mapped = 1;
+out:
+	up(&s->sem);
 	unlock_kernel();
-	return 0;
+	return ret;
 }
 
 
@@ -1368,9 +1428,9 @@
 			break;
 	}
 	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
-		dbg("ioctl %s, arg=0x%x", ioctl_str[count].str, arg);
+		dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg);
 	else
-		dbg("ioctl 0x%s unknown, arg=0x%x", cmd, arg);
+		dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg);
 #endif
 
 	switch (cmd) {
@@ -1609,6 +1669,9 @@
 			s->dma_dac.cnt_factor;
 		abinfo.fragstotal = s->dma_dac.numfrag;
 		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+#ifdef AU1000_VERBOSE_DEBUG
+		dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments);
+#endif
 		return copy_to_user((void *) arg, &abinfo,
 				    sizeof(abinfo)) ? -EFAULT : 0;
 
@@ -1844,6 +1907,7 @@
 
 	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
 	up(&s->open_sem);
+	init_MUTEX(&s->sem);
 	return 0;
 }
 
@@ -1852,8 +1916,13 @@
 	struct au1000_state *s = (struct au1000_state *)file->private_data;
 
 	lock_kernel();
-	if (file->f_mode & FMODE_WRITE)
+	
+	if (file->f_mode & FMODE_WRITE) {
+		unlock_kernel();
 		drain_dac(s, file->f_flags & O_NONBLOCK);
+		lock_kernel();
+	}
+
 	down(&s->open_sem);
 	if (file->f_mode & FMODE_WRITE) {
 		stop_dac(s);
@@ -1906,9 +1975,12 @@
 	// 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));
+	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");
@@ -1964,33 +2036,37 @@
 	}
 	// Allocate the DMA Channels
 	if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
-						   "audio DAC")) < 0) {
+						   "audio DAC",
+						   dac_dma_interrupt,
+						   SA_INTERRUPT, s)) < 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) {
+						   "audio ADC",
+						   adc_dma_interrupt,
+						   SA_INTERRUPT, s)) < 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);
+	     s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr),
+	     s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr));
+
+#ifdef USE_COHERENT_DMA
+	// enable DMA coherency in read/write DMA channels
+	set_dma_mode(s->dma_dac.dmanr,
+		     get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC);
+	set_dma_mode(s->dma_adc.dmanr,
+		     get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC);
+#else
+	// disable DMA coherency in read/write DMA channels
+	set_dma_mode(s->dma_dac.dmanr,
+		     get_dma_mode(s->dma_dac.dmanr) | DMA_NC);
+	set_dma_mode(s->dma_adc.dmanr,
+		     get_dma_mode(s->dma_adc.dmanr) | DMA_NC);
+#endif
 
 	/* register devices */
 
@@ -2089,10 +2165,6 @@
  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;
 }
@@ -2108,8 +2180,6 @@
 		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);
diff -urN linux-2.4.20-pre6/drivers/sound/swarm_cs4297a.c linux-2.4.20-pre7/drivers/sound/swarm_cs4297a.c
--- linux-2.4.20-pre6/drivers/sound/swarm_cs4297a.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/sound/swarm_cs4297a.c	Thu Sep 12 20:01:47 2002
@@ -200,9 +200,6 @@
         }                                          \
 })
 
-#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 {
diff -urN linux-2.4.20-pre6/drivers/tc/lk201-map.map linux-2.4.20-pre7/drivers/tc/lk201-map.map
--- linux-2.4.20-pre6/drivers/tc/lk201-map.map	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/tc/lk201-map.map	Thu Sep 12 20:01:47 2002
@@ -3,8 +3,8 @@
 # Change the above line into
 #	keymaps 0-2,4-6,8,12
 # in case you want the entries
-#	altgr   control keycode  83 = Boot            
-#	altgr   control keycode 111 = Boot            
+#	altgr   control keycode  83 = Boot
+#	altgr   control keycode 111 = Boot
 # below.
 #
 # In fact AltGr is used very little, and one more keymap can
diff -urN linux-2.4.20-pre6/drivers/tc/lk201-remap.c linux-2.4.20-pre7/drivers/tc/lk201-remap.c
--- linux-2.4.20-pre6/drivers/tc/lk201-remap.c	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/tc/lk201-remap.c	Thu Sep 12 20:01:47 2002
@@ -1,17 +1,17 @@
 /*
  * Keyboard mappings for DEC LK201/401/501 keyboards
- * 
+ *
  * 17.05.99 Michael Engel (engel@unix-ag.org)
  *
  * DEC US keyboards generate keycodes in the range 0x55 - 0xfb
  *
- * This conflicts with Linux scancode conventions which define 
+ * This conflicts with Linux scancode conventions which define
  * 0x00-0x7f as "normal" and 0x80-0xff as "shifted" scancodes, so we
  * have to remap the keycodes to 0x00-0x7f with the scancodeRemap
  * array. The generated scancode is simply the number of the key counted
  * from the left upper to the right lower corner of the keyboard ...
  *
- * These scancodes are then being remapped (I hope ;-)) with the 
+ * These scancodes are then being remapped (I hope ;-)) with the
  * lk501*map[] arrays which define scancode -> Linux code mapping
  *
  * Oh man is this horrible ;-)
@@ -91,7 +91,7 @@
 /* ----- 								*/
 /* 60 */ 0,		0,		0,		0,
 /* ----- F6		F7		F8		F9		*/
-/* 64 */ 0x06,		0x07,		0x08,		0x09, 
+/* 64 */ 0x06,		0x07,		0x08,		0x09,
 /* ----- F10								*/
 /* 68 */ 0x0a,		0,		0,		0,
 /* ----- 								*/
diff -urN linux-2.4.20-pre6/drivers/tc/lk201.c linux-2.4.20-pre7/drivers/tc/lk201.c
--- linux-2.4.20-pre6/drivers/tc/lk201.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/tc/lk201.c	Thu Sep 12 20:01:47 2002
@@ -4,7 +4,8 @@
  * 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>
+ * Copyright (C) 1999-2002 Harald Koerfgen <hkoerfg@web.de>
+ * Copyright (C) 2001, 2002  Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  */
 
 #include <linux/config.h>
@@ -20,7 +21,6 @@
 #include <linux/vt_kern.h>
 
 #include <asm/keyboard.h>
-#include <asm/wbflush.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/machtype.h>
 
@@ -47,19 +47,18 @@
 static void lk201_kbd_rx_char(unsigned char, unsigned char);
 
 struct zs_hook lk201_kbdhook = {
-	init_channel:   lk201_init,
-	init_info:      lk201_info,
-	rx_char:        NULL,
-	poll_rx_char:   NULL,
-	poll_tx_char:   NULL,
-	cflags:         B4800 | CS8 | CSTOPB | CLOCAL
+	init_channel:	lk201_init,
+	init_info:	lk201_info,
+	rx_char:	NULL,
+	poll_rx_char:	NULL,
+	poll_tx_char:	NULL,
+	cflags:		B4800 | CS8 | CSTOPB | CLOCAL
 };
 
 /*
  * This is used during keyboard initialisation
  */
 static unsigned char lk201_reset_string[] = {
-	LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf),	/* show we are resetting */
 	LK_CMD_SET_DEFAULTS,
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
@@ -75,27 +74,85 @@
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
 	LK_CMD_MODE(LK_MODE_DOWN, 13),
 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
-	LK_CMD_ENB_RPT,
 	LK_CMD_DIS_KEYCLK,
-	LK_CMD_RESUME,
 	LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
-	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
 };
 
 static struct dec_serial* lk201kbd_info;
 
-static int __init lk201_reset(struct dec_serial *info)
+static int lk201_send(struct dec_serial *info, unsigned char ch)
 {
-	int i;
+	if (info->hook->poll_tx_char(info, ch)) {
+		printk(KERN_ERR "lk201: transmit timeout\n");
+		return -EIO;
+	}
+	return 0;
+}
 
-	for (i = 0; i < sizeof(lk201_reset_string); i++)
-		if (info->hook->poll_tx_char(info, lk201_reset_string[i])) {
-			printk(__FUNCTION__" transmit timeout\n");
-			return -EIO;
-		}
+static inline int lk201_get_id(struct dec_serial *info)
+{
+	return lk201_send(info, LK_CMD_REQ_ID);
+}
+
+static int lk201_reset(struct dec_serial *info)
+{
+	int i, r;
+
+	for (i = 0; i < sizeof(lk201_reset_string); i++) {
+		r = lk201_send(info, lk201_reset_string[i]);
+		if (r < 0)
+			return r;
+	}
 	return 0;
 }
 
+static void lk201_report(unsigned char id[6])
+{
+	char *report = "lk201: keyboard attached, ";
+
+	switch (id[2]) {
+	case LK_STAT_PWRUP_OK:
+		printk(KERN_INFO "%sself-test OK\n", report);
+		break;
+	case LK_STAT_PWRUP_KDOWN:
+		/* The keyboard will resend the power-up ID
+		   after all keys are released, so we don't
+		   bother handling the error specially.  Still
+		   there may be a short-circuit inside.
+		 */
+		printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n",
+		       report, id[3]);
+		break;
+	case LK_STAT_PWRUP_ERROR:
+		printk(KERN_ERR "%sself-test failure\n", report);
+		break;
+	default:
+		printk(KERN_ERR "%sunknown error: 0x%02x\n",
+		       report, id[2]);
+	}
+}
+
+static void lk201_id(unsigned char id[6])
+{
+	/*
+	 * Report whether there is an LK201 or an LK401
+	 * The LK401 has ALT keys...
+	 */
+	switch (id[4]) {
+	case 1:
+		printk(KERN_INFO "lk201: LK201 detected\n");
+		break;
+	case 2:
+		printk(KERN_INFO "lk201: LK401 detected\n");
+		break;
+	default:
+		printk(KERN_WARNING
+		       "lk201: unknown keyboard detected, ID %d\n", id[4]);
+		printk(KERN_WARNING "lk201: ... please report to "
+		       "<linux-mips@oss.sgi.com>\n");
+	}
+}
+
 #define DEFAULT_KEYB_REP_DELAY	(250/5)	/* [5ms] */
 #define DEFAULT_KEYB_REP_RATE	30	/* [cps] */
 
@@ -231,56 +288,92 @@
 
 static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
 {
+	static unsigned char id[6];
+	static int id_i;
+
 	static int shift_state = 0;
 	static int prev_scancode;
 	unsigned char c = scancodeRemap[ch];
 
-	if (!stat || stat == 4) {
-		switch (ch) {
-		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;
-			handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
-			break;
-		case LK_KEY_SHIFT:
-			shift_state ^= LK_SHIFT;
-			handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
-			break;
-		case LK_KEY_CTRL:
-			shift_state ^= LK_CTRL;
-			handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
-			break;
-		case LK_KEY_COMP:
-			shift_state ^= LK_COMP;
-			handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
-			break;
-		case LK_KEY_RELEASE:
-			if (shift_state & LK_SHIFT)
-				handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
-			if (shift_state & LK_CTRL)
-				handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
-			if (shift_state & LK_COMP)
-				handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
-			if (shift_state & LK_LOCK)
-				handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
-			shift_state = 0;
-			break;
-		case LK_KEY_REPEAT:
-			handle_scancode(prev_scancode, 1);
-			break;
-		default:
-			prev_scancode = c;
-			handle_scancode(c, 1);
-			break;
+	if (stat && stat != 4) {
+		printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n",
+		       stat);
+		return;
+	}
+
+	/* Assume this is a power-up ID. */
+	if (ch == LK_STAT_PWRUP_ID && !id_i) {
+		id[id_i++] = ch;
+		return;
+	}
+
+	/* Handle the power-up sequence. */
+	if (id_i) {
+		id[id_i++] = ch;
+		if (id_i == 4) {
+			/* OK, the power-up concluded. */
+			lk201_report(id);
+			if (id[2] == LK_STAT_PWRUP_OK)
+				lk201_get_id(lk201kbd_info);
+			else {
+				id_i = 0;
+				printk(KERN_ERR "lk201: keyboard power-up "
+				       "error, skipping initialization\n");
+			}
+		} else if (id_i == 6) {
+			/* We got the ID; report it and start an operation. */
+			id_i = 0;
+			lk201_id(id);
+			lk201_reset(lk201kbd_info);
 		}
-	} else
-		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
+		return;
+	}
+
+	/* Everything else is a scancode/status response. */
+	id_i = 0;
+	switch (ch) {
+	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;
+		handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
+		break;
+	case LK_KEY_SHIFT:
+		shift_state ^= LK_SHIFT;
+		handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
+		break;
+	case LK_KEY_CTRL:
+		shift_state ^= LK_CTRL;
+		handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
+		break;
+	case LK_KEY_COMP:
+		shift_state ^= LK_COMP;
+		handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
+		break;
+	case LK_KEY_RELEASE:
+		if (shift_state & LK_SHIFT)
+			handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
+		if (shift_state & LK_CTRL)
+			handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
+		if (shift_state & LK_COMP)
+			handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
+		if (shift_state & LK_LOCK)
+			handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
+		shift_state = 0;
+		break;
+	case LK_KEY_REPEAT:
+		handle_scancode(prev_scancode, 1);
+		break;
+	default:
+		prev_scancode = c;
+		handle_scancode(c, 1);
+		break;
+	}
 	tasklet_schedule(&keyboard_tasklet);
 }
 
@@ -290,45 +383,16 @@
 
 static int __init lk201_init(struct dec_serial *info)
 {
-	unsigned int ch, id = 0;
-	int result;
-
-	printk("DECstation LK keyboard driver v0.04... ");
-
-	result = lk201_reset(info);
-	if (result)
-		return result;
-	mdelay(10);
-
-	/*
-	 * Detect whether there is an LK201 or an LK401
-	 * The LK401 has ALT keys...
-	 */
-	info->hook->poll_tx_char(info, LK_CMD_REQ_ID);
-	while ((ch = info->hook->poll_rx_char(info)) > 0)
-		id = ch;
-
-	switch (id) {
-	case 1:
-		printk("LK201 detected\n");
-		break;
-	case 2:
-		printk("LK401 detected\n");
-		break;
-	default:
-		printk("unknown keyboard, ID %d,\n", id);
-		printk("... please report to <linux-mips@oss.sgi.com>\n");
-	}
-
-	/*
-	 * now we're ready
-	 */
-	info->hook->rx_char = lk201_kbd_rx_char;
-
+	/* First install handlers. */
 	lk201kbd_info = info;
 	kbd_rate = lk201kbd_rate;
 	kd_mksound = lk201kd_mksound;
 
+	info->hook->rx_char = lk201_kbd_rx_char;
+
+	/* Then just issue a reset -- the handlers will do the rest. */
+	lk201_send(info, LK_CMD_POWER_UP);
+
 	return 0;
 }
 
@@ -337,26 +401,29 @@
 	extern int register_zs_hook(unsigned int, struct zs_hook *);
 	extern int unregister_zs_hook(unsigned int);
 
+	/* Maxine uses LK501 at the Access.Bus. */
+	if (mips_machtype == MACH_DS5000_XX)
+		return;
+
+	printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n");
+
 	if (TURBOCHANNEL) {
-		if (mips_machtype != MACH_DS5000_XX) {
-			/*
-			 * This is not a MAXINE, so:
-			 *
-			 * kbd_init_hw() is being called before
-			 * rs_init() so just register the kbd hook
-			 * and let zs_init do the rest :-)
-			 */
-			if (mips_machtype == MACH_DS5000_200)
-				printk("LK201 Support for DS5000/200 not yet ready ...\n");
-			else
-				if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
-					unregister_zs_hook(KEYB_LINE);
-		}
+		/*
+		 * kbd_init_hw() is being called before
+		 * rs_init() so just register the kbd hook
+		 * and let zs_init do the rest :-)
+		 */
+		if (mips_machtype == MACH_DS5000_200)
+			printk(KERN_ERR "lk201: support for DS5000/200 "
+			       "not yet ready.\n");
+		else
+			if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
+				unregister_zs_hook(KEYB_LINE);
 	} else {
 		/*
 		 * TODO: modify dz.c to allow similar hooks
 		 * for LK201 handling on DS2100, DS3100, and DS5000/200
 		 */
-		printk("LK201 Support for DS3100 not yet ready ...\n");
+		printk(KERN_ERR "lk201: support for DS3100 not yet ready.\n");
 	}
 }
diff -urN linux-2.4.20-pre6/drivers/tc/lk201.h linux-2.4.20-pre7/drivers/tc/lk201.h
--- linux-2.4.20-pre6/drivers/tc/lk201.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/tc/lk201.h	Thu Sep 12 20:01:47 2002
@@ -20,7 +20,7 @@
 #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 */
+#define LK_CMD_TMP_NORPT	0xd1	/* disable typematic */
 					/* for the currently pressed key */
 #define LK_CMD_ENB_RPT		0xe3	/* enable typematic */
 					/* for RPT_DOWN groups */
@@ -33,15 +33,15 @@
 #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)
+#define LK_CMD_MODE(m,div)	(LK_PARAM|(((div)&0xf)<<3)|(((m)&0x3)<<1))
 					/* select the repeat mode */
 					/* for the selected key group */
-#define LK_CMD_MODE_AR(m,div)	((((div)&0xf)<<3)|m)
+#define LK_CMD_MODE_AR(m,div)	((((div)&0xf)<<3)|(((m)&0x3)<<1))
 					/* 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)))
+#define LK_CMD_RPT_RATE(r)	(0x78|(((r)&0x3)<<1))
 					/* set the delay and repeat rate */
 					/* for the selected repeat register */
 					/* 1st param: initial delay */
@@ -59,8 +59,8 @@
 
 /* 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 */
+#define LK_MODE_RPT_DOWN	0x1	/* make and typematic */
+#define LK_MODE_DOWN_UP		0x3	/* make and release */
 
 /* there are 4 repeat registers */
 #define LK_PARAM_AR(r)		(LK_PARAM|((v)&0x3))
@@ -115,6 +115,7 @@
 					/* the keycode follows */
 #define LK_STAT_MODE_ACK	0xba	/* the mode command succeeded */
 
+#define LK_STAT_PWRUP_ID	0x01	/* the power-up response start mark */
 #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 */
diff -urN linux-2.4.20-pre6/drivers/tc/tc.c linux-2.4.20-pre7/drivers/tc/tc.c
--- linux-2.4.20-pre6/drivers/tc/tc.c	Thu Oct 11 09:43:30 2001
+++ linux-2.4.20-pre7/drivers/tc/tc.c	Thu Sep 12 20:01:47 2002
@@ -8,20 +8,22 @@
  * for more details.
  *
  * Copyright (c) Harald Koerfgen, 1998
+ * Copyright (c) 2001  Maciej W. Rozycki
  */
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
 #include <asm/addrspace.h>
 #include <asm/errno.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tcinfo.h>
 #include <asm/dec/tcmodule.h>
 #include <asm/dec/interrupts.h>
-
+#include <asm/paccess.h>
 #include <asm/ptrace.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
 
 #define TC_DEBUG
 
@@ -32,7 +34,6 @@
 
 unsigned long system_base;
 
-extern void (*dbe_board_handler)(struct pt_regs *regs);
 extern unsigned long *(*rex_slot_address)(int);
 extern void *(*rex_gettcinfo)(void);
 
@@ -40,7 +41,7 @@
  * Interface to the world. Read comment in include/asm-mips/tc.h.
  */
 
-int search_tc_card(char *name)
+int search_tc_card(const char *name)
 {
 	int slot;
 	slot_info *sip;
@@ -93,73 +94,83 @@
 /*
  * Probing for TURBOchannel modules
  */
-static void __init my_dbe_handler(struct pt_regs *regs)
-{
-	regs->cp0_epc += 4;
-}
-
 static void __init tc_probe(unsigned long startaddr, unsigned long size, int max_slot)
 {
-	int i, slot;
+	int i, slot, err;
 	long offset;
+	unsigned char pattern[4];
 	unsigned char *module;
-	void (*old_be_handler)(struct pt_regs *regs);
-
-	/* Install our exception handler temporarily */
 
-	old_be_handler = dbe_board_handler;
-	dbe_board_handler = my_dbe_handler;
 	for (slot = 0; slot <= max_slot; slot++) {
 		module = (char *)(startaddr + slot * size);
-		offset = -1;
-		if (module[OLDCARD + TC_PATTERN0] == 0x55 && module[OLDCARD + TC_PATTERN1] == 0x00
-		  && module[OLDCARD + TC_PATTERN2] == 0xaa && module[OLDCARD + TC_PATTERN3] == 0xff)
-			offset = OLDCARD;
-		if (module[TC_PATTERN0] == 0x55 && module[TC_PATTERN1] == 0x00
-		  && module[TC_PATTERN2] == 0xaa && module[TC_PATTERN3] == 0xff)
-			offset = 0;
-
-		if (offset != -1) {
-			tc_bus[slot].base_addr = (unsigned long)module;
-			for(i = 0; i < 8; i++) {
-				tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i];
-				tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i];
-				tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i];
-			}
-			tc_bus[slot].firmware[8] = 0;
-			tc_bus[slot].vendor[8] = 0;
-			tc_bus[slot].name[8] = 0;
-			/*
-			 * Looks unneccesary, but we may change
-			 * TC? in the future
-			 */
-			switch (slot) {
-			case 0:
-				tc_bus[slot].interrupt = TC0;
-				break;
-			case 1:
-				tc_bus[slot].interrupt = TC1;
-				break;
-			case 2:
-				tc_bus[slot].interrupt = TC2;
-				break;
-			/*
-			 * Yuck! DS5000/200 onboard devices
-			 */
-			case 5:
-				tc_bus[slot].interrupt = SCSI_INT;
-				break;
-			case 6:
-				tc_bus[slot].interrupt = ETHER;
-				break;
-			default:
-				tc_bus[slot].interrupt = -1;
-				break;
-			}	
+
+		offset = OLDCARD;
+
+		err = 0;
+		err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
+		err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
+		err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
+		err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
+		if (err)
+			continue;
+
+		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
+		    pattern[2] != 0xaa || pattern[3] != 0xff) {
+			offset = NEWCARD;
+
+			err = 0;
+			err |= get_dbe(pattern[0], module + TC_PATTERN0);
+			err |= get_dbe(pattern[1], module + TC_PATTERN1);
+			err |= get_dbe(pattern[2], module + TC_PATTERN2);
+			err |= get_dbe(pattern[3], module + TC_PATTERN3);
+			if (err)
+				continue;
 		}
-	}
 
-	dbe_board_handler = old_be_handler;
+		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
+		    pattern[2] != 0xaa || pattern[3] != 0xff)
+			continue;
+
+		tc_bus[slot].base_addr = (unsigned long)module;
+		for(i = 0; i < 8; i++) {
+			tc_bus[slot].firmware[i] =
+				module[TC_FIRM_VER + offset + 4 * i];
+			tc_bus[slot].vendor[i] =
+				module[TC_VENDOR + offset + 4 * i];
+			tc_bus[slot].name[i] =
+				module[TC_MODULE + offset + 4 * i];
+		}
+		tc_bus[slot].firmware[8] = 0;
+		tc_bus[slot].vendor[8] = 0;
+		tc_bus[slot].name[8] = 0;
+		/*
+		 * Looks unneccesary, but we may change
+		 * TC? in the future
+		 */
+		switch (slot) {
+		case 0:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
+			break;
+		case 1:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
+			break;
+		case 2:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
+			break;
+		/*
+		 * Yuck! DS5000/200 onboard devices
+		 */
+		case 5:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
+			break;
+		case 6:
+			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
+			break;
+		default:
+			tc_bus[slot].interrupt = -1;
+			break;
+		}
+	}
 }
 
 /*
@@ -221,7 +232,7 @@
  			i = 2;
 		else
  			i = 1;
- 		
+
  	        system_base = slot0addr + slot_size * (max_tcslot + i);
 
 #ifdef TC_DEBUG
@@ -242,4 +253,4 @@
 EXPORT_SYMBOL(get_tc_base_addr);
 EXPORT_SYMBOL(get_tc_irq_nr);
 EXPORT_SYMBOL(get_tc_speed);
-
+EXPORT_SYMBOL(system_base);
diff -urN linux-2.4.20-pre6/drivers/tc/zs.c linux-2.4.20-pre7/drivers/tc/zs.c
--- linux-2.4.20-pre6/drivers/tc/zs.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/tc/zs.c	Thu Sep 12 20:01:47 2002
@@ -6,7 +6,7 @@
  *
  * DECstation changes
  * Copyright (C) 1998-2000 Harald Koerfgen
- * Copyright (C) 2000,2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ * Copyright (C) 2000, 2001, 2002  Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  *
  * For the rest of the code the original Copyright applies:
  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
@@ -67,7 +67,6 @@
 #include <asm/segment.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
-#include <asm/wbflush.h>
 #include <asm/bootinfo.h>
 #ifdef CONFIG_DECSTATION
 #include <asm/dec/interrupts.h>
@@ -96,7 +95,7 @@
 #define NUM_SERIAL	2		/* Max number of ZS chips supported */
 #define NUM_CHANNELS	(NUM_SERIAL * 2)	/* 2 channels per chip */
 #define CHANNEL_A_NR  (zs_parms->channel_a_offset > zs_parms->channel_b_offset)
-                                        /* Number of channel A in the chip */ 
+                                        /* Number of channel A in the chip */
 #define ZS_CHAN_IO_SIZE 8
 #define ZS_CLOCK        7372800 	/* Z8530 RTxC input clock rate */
 
@@ -107,7 +106,8 @@
 	unsigned long scc1;
 	int channel_a_offset;
 	int channel_b_offset;
-	int irq;
+	int irq0;
+	int irq1;
 	int clock;
 };
 
@@ -119,7 +119,8 @@
 	scc1 : SCC1,
 	channel_a_offset : 1,
 	channel_b_offset : 9,
-	irq : SERIAL,
+	irq0 : -1,
+	irq1 : -1,
 	clock : ZS_CLOCK
 };
 #endif
@@ -129,7 +130,8 @@
 	scc1 : UNI_SCC1,
 	channel_a_offset : 9,
 	channel_b_offset : 1,
-	irq : BAGET_SCC_IRQ,
+	irq0 : BAGET_SCC_IRQ,
+	irq1 : BAGET_SCC_IRQ,
 	clock : 14745000
 };
 #endif
@@ -263,7 +265,7 @@
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
 	9600, 19200, 38400, 57600, 115200, 0 };
 
-/* 
+/*
  * Reading and writing Z8530 registers.
  */
 static inline unsigned char read_zsreg(struct dec_zschannel *channel,
@@ -273,7 +275,7 @@
 
 	if (reg != 0) {
 		*channel->control = reg & 0xf;
-		wbflush(); RECOVERY_DELAY;
+		fast_iob(); RECOVERY_DELAY;
 	}
 	retval = *channel->control;
 	RECOVERY_DELAY;
@@ -285,10 +287,10 @@
 {
 	if (reg != 0) {
 		*channel->control = reg & 0xf;
-		wbflush(); RECOVERY_DELAY;
+		fast_iob(); RECOVERY_DELAY;
 	}
 	*channel->control = value;
-	wbflush(); RECOVERY_DELAY;
+	fast_iob(); RECOVERY_DELAY;
 	return;
 }
 
@@ -305,7 +307,7 @@
 				unsigned char value)
 {
 	*channel->data = value;
-	wbflush(); RECOVERY_DELAY;
+	fast_iob(); RECOVERY_DELAY;
 	return;
 }
 
@@ -409,7 +411,7 @@
 		stat = read_zsreg(info->zs_channel, R1);
 		ch = read_zsdata(info->zs_channel);
 
-		if (!tty && !info->hook && !info->hook->rx_char)
+		if (!tty && (!info->hook || !info->hook->rx_char))
 			continue;
 
 		if (tty_break) {
@@ -456,7 +458,7 @@
 			(*info->hook->rx_char)(ch, flag);
 			return;
   		}
-		
+
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			static int flip_buf_ovf;
 			++flip_buf_ovf;
@@ -471,7 +473,9 @@
 
 		*tty->flip.flag_buf_ptr++ = flag;
 		*tty->flip.char_buf_ptr++ = ch;
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
 	ignore_char:
+#endif
 	}
 	if (tty)
 		tty_flip_buffer_push(tty);
@@ -522,9 +526,9 @@
 
 	if (info->zs_channel != info->zs_chan_a) {
 
-		/* FIXEM: Check for DCD transitions */
-		if (((stat ^ info->read_reg_zero) & DCD) != 0
-		    && info->tty && !C_CLOCAL(info->tty)) {
+		/* Check for DCD transitions */
+		if (info->tty && !C_CLOCAL(info->tty) &&
+		    ((stat ^ info->read_reg_zero) & DCD) != 0 ) {
 			if (stat & DCD) {
 				wake_up_interruptible(&info->open_wait);
 			} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
@@ -575,7 +579,7 @@
 		shift = 0;	/* Channel B */
 
 	for (;;) {
-		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift; 
+		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift;
 		if ((zs_intreg & CHAN_IRQMASK) == 0)
 			break;
 
@@ -589,7 +593,7 @@
 			status_handle(info);
 		}
 	}
-	
+
 	/* Why do we need this ? */
 	write_zsreg(info->zs_channel, 0, RES_H_IUS);
 }
@@ -598,14 +602,14 @@
 void zs_dump (void) {
 	int i, j;
 	for (i = 0; i < zs_channels_found; i++) {
-		struct dec_zschannel *ch = &zs_channels[i]; 
+		struct dec_zschannel *ch = &zs_channels[i];
 		if ((long)ch->control == UNI_IO_BASE+UNI_SCC1A_CTRL) {
 			for (j = 0; j < 15; j++) {
-				printk("W%d = 0x%x\t", 
+				printk("W%d = 0x%x\t",
 				       j, (int)ch->curregs[j]);
 			}
 			for (j = 0; j < 15; j++) {
-				printk("R%d = 0x%x\t", 
+				printk("R%d = 0x%x\t",
 				       j, (int)read_zsreg(ch,j));
 			}
 			printk("\n\n");
@@ -634,7 +638,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 #if 1
 	save_flags(flags); cli();
 	if (info->zs_channel->curregs[5] & TxENAB) {
@@ -649,10 +653,10 @@
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
 	unsigned long flags;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_start"))
 		return;
-	
+
 	save_flags(flags); cli();
 #if 1
 	if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) {
@@ -685,7 +689,7 @@
 {
 	struct dec_serial	*info = (struct dec_serial *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -786,9 +790,9 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       info->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
-	
+
 	if (info->xmit_buf) {
 		free_page((unsigned long) info->xmit_buf);
 		info->xmit_buf = 0;
@@ -854,7 +858,7 @@
 		brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor);
 		info->zs_channel->curregs[12] = (brg & 255);
 		info->zs_channel->curregs[13] = ((brg >> 8) & 255);
-		zs_rtsdtr(info, DTR, 1); 
+		zs_rtsdtr(info, DTR, 1);
 	} else {
 		zs_rtsdtr(info, RTS | DTR, 0);
 		return;
@@ -957,7 +961,7 @@
 
 	save_flags(flags);
 	while (1) {
-		cli();		
+		cli();
 		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				   SERIAL_XMIT_SIZE - info->xmit_head));
 		if (c <= 0)
@@ -991,7 +995,7 @@
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
 	int	ret;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
 		return 0;
 	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
@@ -1003,7 +1007,7 @@
 static int rs_chars_in_buffer(struct tty_struct *tty)
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
-			
+
 	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
 		return 0;
 	return info->xmit_cnt;
@@ -1012,7 +1016,7 @@
 static void rs_flush_buffer(struct tty_struct *tty)
 {
 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
 	cli();
@@ -1027,7 +1031,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1039,14 +1043,14 @@
 
 #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)) {
 		save_flags(flags); cli();
 		info->x_char = STOP_CHAR(tty);
@@ -1067,14 +1071,14 @@
 
 #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)) {
 		save_flags(flags); cli();
 		if (info->x_char)
@@ -1171,7 +1175,7 @@
  * 	    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. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct dec_serial * info, unsigned int *value)
 {
@@ -1232,7 +1236,7 @@
 		info->zs_chan_a->curregs[5] &= ~bits;
 		break;
 	case TIOCMSET:
-		info->zs_chan_a->curregs[5] = 
+		info->zs_chan_a->curregs[5] =
 			(info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits;
 		break;
 	default:
@@ -1284,7 +1288,7 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
 		case TIOCMGET:
 			error = verify_area(VERIFY_WRITE, (void *) arg,
@@ -1322,7 +1326,7 @@
 			copy_from_user((struct dec_serial *) arg,
 				       info, sizeof(struct dec_serial));
 			return 0;
-			
+
 		default:
 			return -ENOIOCTLCMD;
 		}
@@ -1347,7 +1351,7 @@
 /*
  * ------------------------------------------------------------
  * rs_close()
- * 
+ *
  * This routine is called when the serial port gets closed.
  * Wait for the last remaining data to be sent.
  * ------------------------------------------------------------
@@ -1359,14 +1363,14 @@
 
 	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
 		return;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		restore_flags(flags);
 		return;
 	}
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_close ttyS%02d, count = %d\n", info->line, info->count);
 #endif
@@ -1401,7 +1405,7 @@
 	if (info->flags & ZILOG_CALLOUT_ACTIVE)
 		info->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1542,7 +1546,7 @@
 		info->flags |= ZILOG_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.
@@ -1562,7 +1566,7 @@
 		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
@@ -1577,7 +1581,7 @@
 	       info->line, info->count);
 #endif
 	cli();
-	if (!tty_hung_up_p(filp)) 
+	if (!tty_hung_up_p(filp))
 		info->count--;
 	sti();
 	info->blocked_open++;
@@ -1594,7 +1598,7 @@
 			if (info->flags & ZILOG_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -1627,7 +1631,7 @@
 		return retval;
 	info->flags |= ZILOG_NORMAL_ACTIVE;
 	return 0;
-}	
+}
 
 /*
  * This routine is called whenever a serial port is opened.  It
@@ -1693,7 +1697,7 @@
 	if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->normal_termios;
-		else 
+		else
 			*tty->termios = info->callout_termios;
 		change_speed(info);
 	}
@@ -1719,7 +1723,7 @@
 
 static void __init show_serial_version(void)
 {
-	printk("DECstation Z8530 serial driver version 0.05\n");
+	printk("DECstation Z8530 serial driver version 0.07\n");
 }
 
 /*  Initialize Z8530s zs_channels
@@ -1737,7 +1741,7 @@
 		printk("Not on JUNKIO machine, skipping probe_sccs\n");
 		return;
 	}
-	
+
 	/*
 	 * When serial console is activated, tc_init has not been called yet
 	 * and system_base is undefined. Unfortunately we have to hardcode
@@ -1749,16 +1753,21 @@
 		system_base = 0xbf800000;
 		n_chips = 2;
 		zs_parms = &ds_parms;
+		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
 		break;
 	case MACH_DS5000_1XX:
 		system_base = 0xbc000000;
 		n_chips = 2;
 		zs_parms = &ds_parms;
+		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
 		break;
 	case MACH_DS5000_XX:
 		system_base = 0xbc000000;
 		n_chips = 1;
 		zs_parms = &ds_parms;
+		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
 		break;
 #endif
 #ifdef CONFIG_BAGET_MIPS
@@ -1784,12 +1793,12 @@
 			/*
 			 * The sccs reside on the high byte of the 16 bit IOBUS
 			 */
-			zs_channels[n_channels].control = 
-				(volatile unsigned char *)system_base + 
-			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) + 
-			  (0 == channel ? zs_parms->channel_a_offset : 
+			zs_channels[n_channels].control =
+				(volatile unsigned char *)system_base +
+			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
+			  (0 == channel ? zs_parms->channel_a_offset :
 			                  zs_parms->channel_b_offset);
-			zs_channels[n_channels].data = 
+			zs_channels[n_channels].data =
 				zs_channels[n_channels].control + 4;
 
 #ifndef CONFIG_SERIAL_CONSOLE
@@ -1807,20 +1816,24 @@
 				       ZS_CHAN_IO_SIZE, "SCC");
 #endif
 			zs_soft[n_channels].zs_channel = &zs_channels[n_channels];
-			zs_soft[n_channels].irq = zs_parms->irq;
+			/* HACK alert! */
+			if (!(chip & 1))
+				zs_soft[n_channels].irq = zs_parms->irq0;
+			else
+				zs_soft[n_channels].irq = zs_parms->irq1;
 
-			/* 
+			/*
 			 *  Identification of channel A. Location of channel A
                          *  inside chip depends on mapping of internal address
 			 *  the chip decodes channels by.
-			 *  CHANNEL_A_NR returns either 0 (in case of 
+			 *  CHANNEL_A_NR returns either 0 (in case of
 			 *  DECstations) or 1 (in case of Baget).
 			 */
 			if (CHANNEL_A_NR == channel)
-				zs_soft[n_channels].zs_chan_a = 
+				zs_soft[n_channels].zs_chan_a =
 				    &zs_channels[n_channels+1-2*CHANNEL_A_NR];
 			else
-				zs_soft[n_channels].zs_chan_a = 
+				zs_soft[n_channels].zs_chan_a =
 				    &zs_channels[n_channels];
 
 			*pp = &zs_soft[n_channels];
@@ -1846,7 +1859,7 @@
 			write_zsreg(zs_soft[n].zs_chan_a, R9, 0);
 		}
 		load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs);
-	} 
+	}
 	restore_flags(flags); */
 }
 
@@ -1932,34 +1945,30 @@
 	save_flags(flags); cli();
 
 	for (channel = 0; channel < zs_channels_found; ++channel) {
-		if (zs_soft[channel].hook &&
-		    zs_soft[channel].hook->init_channel)
-			(*zs_soft[channel].hook->init_channel)
-				(&zs_soft[channel]);
+		if (request_irq(zs_soft[channel].irq, rs_interrupt, SA_SHIRQ,
+				"scc", &zs_soft[channel]))
+			printk(KERN_ERR "decserial: can't get irq %d\n",
+			       zs_soft[channel].irq);
 
 		zs_soft[channel].clk_divisor = 16;
 		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
-
-		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,
-				"SCC", &zs_soft[channel]))
-			printk(KERN_ERR "decserial: can't get irq %d\n",
-			       zs_parms->irq);
 	}
 
-	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
-	{
-		if (info->hook && info->hook->init_info) {
-			(*info->hook->init_info)(info);
+	for (info = zs_chain, i = 0; info; info = info->zs_next, i++) {
+
+		/* Needed before interrupts are enabled. */
+		info->tty = 0;
+		info->x_char = 0;
+
+		if (info->hook && info->hook->init_info)
 			continue;
-		}
+
 		info->magic = SERIAL_MAGIC;
 		info->port = (int) info->zs_channel->control;
 		info->line = i;
-		info->tty = 0;
 		info->custom_divisor = 16;
 		info->close_delay = 50;
 		info->closing_wait = 3000;
-		info->x_char = 0;
 		info->event = 0;
 		info->count = 0;
 		info->blocked_open = 0;
@@ -1969,7 +1978,7 @@
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
-		printk("ttyS%02d at 0x%08x (irq = %d)", info->line, 
+		printk("ttyS%02d at 0x%08x (irq = %d)", info->line,
 		       info->port, info->irq);
 		printk(" is a Z85C30 SCC\n");
 		tty_register_devfs(&serial_driver, 0,
@@ -1981,6 +1990,18 @@
 
 	restore_flags(flags);
 
+	for (channel = 0; channel < zs_channels_found; ++channel) {
+		if (zs_soft[channel].hook &&
+		    zs_soft[channel].hook->init_channel)
+			(*zs_soft[channel].hook->init_channel)
+				(&zs_soft[channel]);
+	}
+
+	for (info = zs_chain, i = 0; info; info = info->zs_next, i++) {
+		if (info->hook && info->hook->init_info)
+			(*info->hook->init_info)(info);
+	}
+
 	return 0;
 }
 
@@ -2010,32 +2031,19 @@
 
 	if(chan) {
 		int loops = 10000;
-//		int nine = read_zsreg(chan, R9);
-
-		RECOVERY_DELAY;
-//        	write_zsreg(chan, R9, nine & ~MIE);
-               	wbflush();
-		RECOVERY_DELAY;
-
-        	while (!(*(chan->control) & Tx_BUF_EMP) && --loops)
-	        	RECOVERY_DELAY;
-
-                if (loops) {
-                        ret = 0;
-        	        *(chan->data) = ch;
-                	wbflush();
-			RECOVERY_DELAY;
-                } else
-                        ret = -EAGAIN;
 
-//        	write_zsreg(chan, R9, nine);
-               	wbflush();
-		RECOVERY_DELAY;
+		while (loops && !(read_zsreg(chan, 0) & Tx_BUF_EMP))
+			loops--;
 
-                return ret;
-        }
+		if (loops) {
+			write_zsdata(chan, ch);
+			ret = 0;
+		} else
+			ret = -EAGAIN;
 
-	return -ENODEV;
+		return ret;
+	} else
+		return -ENODEV;
 }
 
 static int
@@ -2047,17 +2055,17 @@
 	if(chan) {
                 int loops = 10000;
 
-                while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)
-		        loops--;
+		while (loops && !(read_zsreg(chan, 0) & Rx_CH_AV))
+			loops--;
 
                 if (loops)
                         ret = read_zsdata(chan);
                 else
                         ret = -EAGAIN;
 
-                return ret;
-        } else
-                return -ENODEV;
+		return ret;
+	} else
+		return -ENODEV;
 }
 
 unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook)
@@ -2215,7 +2223,7 @@
 		break;
 	}
 	co->cflag = cflag;
-#if 1 
+#if 1
 	save_and_cli(flags);
 
 	/*
@@ -2321,7 +2329,7 @@
 	write_zsreg(chan, 9, nine);
 }
 
-static int kgdbhook_init_channel(struct dec_serial* info) 
+static int kgdbhook_init_channel(struct dec_serial* info)
 {
 	return 0;
 }
@@ -2330,7 +2338,7 @@
 {
 }
 
-static void kgdbhook_rx_char(struct dec_serial* info, 
+static void kgdbhook_rx_char(struct dec_serial* info,
 			     unsigned char ch, unsigned char stat)
 {
 	if (ch == 0x03 || ch == '$')
diff -urN linux-2.4.20-pre6/drivers/tc/zs.h linux-2.4.20-pre7/drivers/tc/zs.h
--- linux-2.4.20-pre6/drivers/tc/zs.h	Mon Aug 27 08:56:31 2001
+++ linux-2.4.20-pre7/drivers/tc/zs.h	Thu Sep 12 20:01:47 2002
@@ -38,7 +38,7 @@
 /*
  * Definitions for ZILOG_struct (and serial_struct) flags field
  */
-#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
+#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes
 				   on the callout port */
 #define ZILOG_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
 #define ZILOG_SAK	0x0004	/* Secure Attention Key (Orange book) */
@@ -74,7 +74,7 @@
 #ifdef __KERNEL__
 /*
  * This is our internal structure for each serial port's state.
- * 
+ *
  * Many fields are paralleled by the structure used by the serial_struct
  * structure.
  *
diff -urN linux-2.4.20-pre6/drivers/usb/devices.c linux-2.4.20-pre7/drivers/usb/devices.c
--- linux-2.4.20-pre6/drivers/usb/devices.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/usb/devices.c	Thu Sep 12 20:01:48 2002
@@ -61,6 +61,8 @@
 #include <linux/usbdevice_fs.h>
 #include <asm/uaccess.h>
 
+#include "hcd.h"
+
 #define MAX_TOPO_LEVEL		6
 
 /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
diff -urN linux-2.4.20-pre6/drivers/usb/hc_sl811.c linux-2.4.20-pre7/drivers/usb/hc_sl811.c
--- linux-2.4.20-pre6/drivers/usb/hc_sl811.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/hc_sl811.c	Thu Sep 12 20:01:48 2002
@@ -1162,6 +1162,7 @@
 	}
 
 	hci->bus = bus;
+	bus->bus_name = "sl811";
 	bus->hcpriv = (void *) hci;
 
 	return hci;
diff -urN linux-2.4.20-pre6/drivers/usb/hcd.c linux-2.4.20-pre7/drivers/usb/hcd.c
--- linux-2.4.20-pre6/drivers/usb/hcd.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/hcd.c	Thu Sep 12 20:01:48 2002
@@ -56,7 +56,8 @@
  * USB Host Controller Driver framework
  *
  * Plugs into usbcore (usb_bus) and lets HCDs share code, minimizing
- * HCD-specific behaviors/bugs.
+ * HCD-specific behaviors/bugs.  Think of it as the "upper level" of
+ * some drivers, where the "lower level" is hardware-specific.
  *
  * 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
@@ -78,6 +79,9 @@
  * Roman Weissgaerber, Rory Bolt, ...
  *
  * HISTORY:
+ * 2002-sept	Merge some 2.5 updates so we can share hardware level HCD
+ * 	code between the 2.4.20+ and 2.5 trees.
+ * 2002-feb	merge to 2.4.19
  * 2001-12-12	Initial patch version for Linux 2.5.1 kernel.
  */
 
@@ -583,7 +587,6 @@
 	struct hc_driver	*driver;
 	unsigned long		resource, len;
 	void			*base;
-	u8			latency, limit;
 	struct usb_bus		*bus;
 	struct usb_hcd		*hcd;
 	int			retval, region;
@@ -662,15 +665,6 @@
 	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
@@ -701,7 +695,8 @@
 		goto clean_3;
 	}
 	hcd->bus = bus;
-	hcd->bus_name = dev->slot_name;
+	hcd->bus_name = dev->slot_name;		/* prefer bus->bus_name */
+	bus->bus_name = dev->slot_name;
 	hcd->product_desc = dev->name;
 	bus->hcpriv = (void *) hcd;
 
@@ -1072,6 +1067,8 @@
 	if (urb->transfer_buffer_length < 0)
 		return -EINVAL;
 
+	// FIXME set urb->transfer_dma and/or setup_dma 
+
 	if (urb->next) {
 		warn ("use explicit queuing not urb->next");
 		return -EINVAL;
@@ -1463,6 +1460,8 @@
 		dbg ("giveback urb %p status %d len %d",
 			urb, urb->status, urb->actual_length);
 
+	// FIXME unmap urb->transfer_dma and/or setup_dma 
+
 	/* pass ownership to the completion handler */
 	urb->complete (urb);
 }
diff -urN linux-2.4.20-pre6/drivers/usb/hcd.h linux-2.4.20-pre7/drivers/usb/hcd.h
--- linux-2.4.20-pre6/drivers/usb/hcd.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre7/drivers/usb/hcd.h	Thu Sep 12 20:01:48 2002
@@ -153,6 +153,7 @@
 
 #ifdef CONFIG_PCI
 
+struct pci_device_id;
 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);
@@ -206,6 +207,54 @@
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * Generic bandwidth allocation constants/support
+ */
+#define FRAME_TIME_USECS	1000L
+#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
+		/* Trying not to use worst-case bit-stuffing
+                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
+		/* bytecount = data payload byte count */
+
+#define NS_TO_US(ns)	((ns + 500L) / 1000L)
+			/* convert & round nanoseconds to microseconds */
+
+extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
+		int bustime, int isoc);
+extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
+		int isoc);
+
+/*
+ * Full/low speed bandwidth allocation constants/support.
+ */
+#define BW_HOST_DELAY	1000L		/* nanoseconds */
+#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
+                        /* 4 full-speed bit times (est.) */
+
+#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
+#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
+#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)
+
+extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
+
+/*
+ * 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 USB2_HOST_DELAY	5	/* nsec, guess */
+#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
+	+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+	+ USB2_HOST_DELAY)
+#define HS_USECS_ISO(bytes) NS_TO_US ( ((long)(38 * 8 * 2.083)) \
+	+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+	+ USB2_HOST_DELAY)
+
+extern long usb_calc_bus_time (int speed, int is_input,
+			int isoc, int bytecount);
+
+/*-------------------------------------------------------------------------*/
+
 /* 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
@@ -217,3 +266,20 @@
 
 #define	RUN_CONTEXT (in_irq () ? "in_irq" \
 		: (in_interrupt () ? "in_interrupt" : "can sleep"))
+
+/* 2.5 changes ... */
+
+#ifndef container_of
+#define	container_of	list_entry
+#endif
+
+#define usb_get_urb(x) (x)
+#define usb_put_urb(x)
+
+static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
+	{ return hcd->bus; }
+
+static inline void
+usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe)
+	{ }
+
diff -urN linux-2.4.20-pre6/drivers/usb/hpusbscsi.c linux-2.4.20-pre7/drivers/usb/hpusbscsi.c
--- linux-2.4.20-pre6/drivers/usb/hpusbscsi.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/hpusbscsi.c	Thu Sep 12 20:01:48 2002
@@ -207,7 +207,13 @@
 static struct usb_device_id hpusbscsi_usb_ids[] = {
 	{USB_DEVICE (0x03f0, 0x0701)},	/* HP 53xx */
 	{USB_DEVICE (0x03f0, 0x0801)},	/* HP 7400 */
+	{USB_DEVICE (0x0638, 0x0268)},  /*iVina 1200U */
 	{USB_DEVICE (0x0638, 0x026a)},	/*Scan Dual II */
+	{USB_DEVICE (0x0638, 0x0A13)},  /*Avision AV600U */
+	{USB_DEVICE (0x0638, 0x0A16)},  /*Avision DS610CU Scancopier */
+	{USB_DEVICE (0x0638, 0x0A18)},  /*Avision AV600U Plus */
+	{USB_DEVICE (0x0638, 0x0A23)},  /*Avision AV220 */
+	{USB_DEVICE (0x0638, 0x0A24)},  /*Avision AV210 */
 	{USB_DEVICE (0x0686, 0x4004)},  /*Minolta Elite II */
 	{}			/* Terminating entry */
 };
diff -urN linux-2.4.20-pre6/drivers/usb/hub.c linux-2.4.20-pre7/drivers/usb/hub.c
--- linux-2.4.20-pre6/drivers/usb/hub.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/hub.c	Thu Sep 12 20:01:48 2002
@@ -678,7 +678,6 @@
 	struct usb_device *dev;
 	unsigned int delay = HUB_SHORT_RESET_TIME;
 	int i;
-	char *portstr, *tempstr;
 
 	dbg("port %d, portstatus %x, change %x, %s",
 		port + 1, portstatus, portchange, portspeed (portstatus));
@@ -706,11 +705,9 @@
 
 	down(&usb_address0_sem);
 
-	tempstr = kmalloc(1024, GFP_KERNEL);
-	portstr = kmalloc(1024, GFP_KERNEL);
-
 	for (i = 0; i < HUB_PROBE_TRIES; i++) {
-		struct usb_device *pdev, *cdev;
+		struct usb_device *pdev;
+		int len;
 
 		/* Allocate a new device struct */
 		dev = usb_alloc_dev(hub, hub->bus);
@@ -740,32 +737,28 @@
 			dev->ttport = port + 1;
 		}
 
-		/* Create a readable topology string */
-		cdev = dev;
+		/* Save readable and stable topology id, distinguishing
+		 * devices by location for diagnostics, tools, etc.  The
+		 * string is a path along hub ports, from the root.  Each
+		 * device's id will be stable until USB is re-cabled, and
+		 * hubs are often labeled with these port numbers.
+		 *
+		 * Initial size: ".NN" times five hubs + NUL = 16 bytes max
+		 * (quite rare, since most hubs have 4-6 ports).
+		 */
 		pdev = dev->parent;
-		if (portstr && tempstr) {
-			portstr[0] = 0;
-			while (pdev) {
-				int port;
-
-				for (port = 0; port < pdev->maxchild; port++)
-					if (pdev->children[port] == cdev)
-						break;
-
-				strcpy(tempstr, portstr);
-				if (!strlen(tempstr))
-					sprintf(portstr, "%d", port + 1);
-				else
-					sprintf(portstr, "%d/%s", port + 1, tempstr);
-
-				cdev = pdev;
-				pdev = pdev->parent;
-			}
-			info("USB new device connect on bus%d/%s, assigned device number %d",
-				dev->bus->busnum, portstr, dev->devnum);
-		} else
-			info("USB new device connect on bus%d, assigned device number %d",
-				dev->bus->busnum, dev->devnum);
+		if (pdev->devpath [0] != '0')	/* parent not root? */
+			len = snprintf (dev->devpath, sizeof dev->devpath,
+				"%s.%d", pdev->devpath, port + 1);
+		/* root == "0", root port 2 == "2", port 3 that hub "2.3" */
+		else
+			len = snprintf (dev->devpath, sizeof dev->devpath,
+				"%d", port + 1);
+		if (len == sizeof dev->devpath)
+			warn ("devpath size! usb/%03d/%03d path %s",
+				dev->bus->busnum, dev->devnum, dev->devpath);
+		info("new USB device %s-%s, assigned address %d",
+			dev->bus->bus_name, dev->devpath, dev->devnum);
 
 		/* Run it through the hoops (find a driver, etc) */
 		if (!usb_new_device(dev))
@@ -782,10 +775,6 @@
 	usb_hub_port_disable(hub, port);
 done:
 	up(&usb_address0_sem);
-	if (portstr)
-		kfree(portstr);
-	if (tempstr)
-		kfree(tempstr);
 }
 
 static void usb_hub_events(void)
diff -urN linux-2.4.20-pre6/drivers/usb/scanner.c linux-2.4.20-pre7/drivers/usb/scanner.c
--- linux-2.4.20-pre6/drivers/usb/scanner.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/scanner.c	Thu Sep 12 20:01:48 2002
@@ -771,7 +771,7 @@
  		if (copy_from_user(&cmsg, (void *)arg, sizeof(cmsg)))
  			return -EFAULT;
 
- 		nb = le16_to_cpup(&cmsg.req.wLength);
+ 		nb = cmsg.req.wLength;
 
  		if (nb > sizeof(buf))
  			return -EINVAL;
@@ -786,8 +786,8 @@
 
  		ret = usb_control_msg(dev, pipe, cmsg.req.bRequest,
  				      cmsg.req.bRequestType,
- 				      le16_to_cpup(&cmsg.req.wValue),
- 				      le16_to_cpup(&cmsg.req.wIndex),
+ 				      cmsg.req.wValue,
+ 				      cmsg.req.wIndex,
  				      buf, nb, HZ);
 
  		if (ret < 0) {
diff -urN linux-2.4.20-pre6/drivers/usb/serial/belkin_sa.c linux-2.4.20-pre7/drivers/usb/serial/belkin_sa.c
--- linux-2.4.20-pre6/drivers/usb/serial/belkin_sa.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/serial/belkin_sa.c	Thu Sep 12 20:01:48 2002
@@ -108,6 +108,7 @@
 	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
 	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
 	{ USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
+	{ USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) },
 	{ USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
 	{ }							/* Terminating entry */
 };
diff -urN linux-2.4.20-pre6/drivers/usb/serial/belkin_sa.h linux-2.4.20-pre7/drivers/usb/serial/belkin_sa.h
--- linux-2.4.20-pre6/drivers/usb/serial/belkin_sa.h	Mon Oct  1 13:45:43 2001
+++ linux-2.4.20-pre7/drivers/usb/serial/belkin_sa.h	Thu Sep 12 20:01:48 2002
@@ -47,6 +47,7 @@
 
 #define GOHUBS_VID	0x0921	/* GoHubs vendor id */
 #define GOHUBS_PID	0x1000	/* GoHubs single port serial converter's id (identical to the Peracom device) */
+#define HANDYLINK_PID	0x1200	/* HandyLink USB's id (identical to the Peracom device) */
 
 /* Vendor Request Interface */
 #define BELKIN_SA_SET_BAUDRATE_REQUEST	0  /* Set baud rate */
diff -urN linux-2.4.20-pre6/drivers/usb/serial/usbserial.c linux-2.4.20-pre7/drivers/usb/serial/usbserial.c
--- linux-2.4.20-pre6/drivers/usb/serial/usbserial.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/serial/usbserial.c	Thu Sep 12 20:01:48 2002
@@ -814,7 +814,7 @@
 	int length = 0;
 	int i;
 	off_t begin = 0;
-//	char tmp[40];
+	char tmp[40];
 
 	dbg("%s", __FUNCTION__);
 	length += sprintf (page, "usbserinfo:1.0 driver:%s\n", DRIVER_VERSION);
@@ -831,8 +831,8 @@
 		length += sprintf (page+length, " num_ports:%d", serial->num_ports);
 		length += sprintf (page+length, " port:%d", i - serial->minor + 1);
 
-//		usb_make_path(serial->dev, tmp, sizeof(tmp));
-//		length += sprintf (page+length, " path:%s", tmp);
+		usb_make_path(serial->dev, tmp, sizeof(tmp));
+		length += sprintf (page+length, " path:%s", tmp);
 			
 		length += sprintf (page+length, "\n");
 		if ((length + begin) > (off + count))
diff -urN linux-2.4.20-pre6/drivers/usb/uhci.c linux-2.4.20-pre7/drivers/usb/uhci.c
--- linux-2.4.20-pre6/drivers/usb/uhci.c	Thu Sep 12 20:01:35 2002
+++ linux-2.4.20-pre7/drivers/usb/uhci.c	Thu Sep 12 20:01:48 2002
@@ -57,6 +57,8 @@
 
 #include <linux/pm.h>
 
+#include "hcd.h"
+
 /*
  * Version Information
  */
@@ -2797,6 +2799,7 @@
 	}
 
 	uhci->bus = bus;
+	bus->bus_name = dev->slot_name;
 	bus->hcpriv = uhci;
 
 	usb_register_bus(uhci->bus);
diff -urN linux-2.4.20-pre6/drivers/usb/usb-ohci.c linux-2.4.20-pre7/drivers/usb/usb-ohci.c
--- linux-2.4.20-pre6/drivers/usb/usb-ohci.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/usb/usb-ohci.c	Thu Sep 12 20:01:48 2002
@@ -78,6 +78,7 @@
 
 #include "usb-ohci.h"
 
+#include "hcd.h"
 
 #ifdef CONFIG_PMAC_PBOOK
 #include <asm/machdep.h>
@@ -2413,6 +2414,7 @@
 		kfree (ohci);
 		return NULL;
 	}
+	ohci->bus->bus_name = dev->slot_name;
 	ohci->bus->hcpriv = (void *) ohci;
 
 	return ohci;
@@ -2440,8 +2442,9 @@
 	}
 	pci_set_drvdata(ohci->ohci_dev, NULL);
 	if (ohci->bus) {
-		if (ohci->bus->busnum)
+		if (ohci->bus->busnum != -1)
 			usb_deregister_bus (ohci->bus);
+
 		usb_free_bus (ohci->bus);
 	}
 
@@ -2470,7 +2473,6 @@
 	void *mem_base, const struct pci_device_id *id)
 {
 	ohci_t * ohci;
-	u8 latency, limit;
 	char buf[8], *bufp = buf;
 	int ret;
 
@@ -2510,20 +2512,6 @@
 	if (ohci->flags & OHCI_QUIRK_AMD756)
 		printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
 
-	/* bad pci latencies can contribute to overruns */ 
-	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);
-			ohci->pci_latency = limit;
-		} else {
-			/* it might already have been reduced */
-			ohci->pci_latency = latency;
-		}
-	}
-
 	if (hc_reset (ohci) < 0) {
 		hc_release_ohci (ohci);
 		return -ENODEV;
diff -urN linux-2.4.20-pre6/drivers/usb/usb-uhci.c linux-2.4.20-pre7/drivers/usb/usb-uhci.c
--- linux-2.4.20-pre6/drivers/usb/usb-uhci.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/usb/usb-uhci.c	Thu Sep 12 20:01:48 2002
@@ -59,6 +59,8 @@
 #include "usb-uhci.h"
 #include "usb-uhci-debug.h"
 
+#include "hcd.h"
+
 /*
  * Version Information
  */
@@ -2952,6 +2954,7 @@
 	}
 
 	s->bus = bus;
+	bus->bus_name = dev->slot_name;
 	bus->hcpriv = s;
 
 	/* UHCI specs says devices must have 2 ports, but goes on to say */
diff -urN linux-2.4.20-pre6/drivers/usb/usb.c linux-2.4.20-pre7/drivers/usb/usb.c
--- linux-2.4.20-pre6/drivers/usb/usb.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/usb/usb.c	Thu Sep 12 20:01:48 2002
@@ -38,6 +38,8 @@
 #endif
 #include <linux/usb.h>
 
+#include "hcd.h"
+
 static const int usb_bandwidth_option =
 #ifdef CONFIG_USB_BANDWIDTH
 				1;
@@ -218,42 +220,51 @@
 }
 
 /*
- * usb_calc_bus_time:
- *
- * returns (approximate) USB bus time in nanoseconds for a USB transaction.
+ * usb_calc_bus_time - approximate periodic transaction time in nanoseconds
+ * @speed: from dev->speed; USB_SPEED_{LOW,FULL,HIGH}
+ * @is_input: true iff the transaction sends data to the host
+ * @isoc: true for isochronous transactions, false for interrupt ones
+ * @bytecount: how many bytes in the transaction.
+ *
+ * Returns approximate bus time in nanoseconds for a periodic transaction.
+ * See USB 2.0 spec section 5.11.3; only periodic transfers need to be
+ * scheduled in software, this function is only used for such scheduling.
  */
-static long usb_calc_bus_time (int low_speed, int input_dir, int isoc, int bytecount)
+long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
 {
 	unsigned long	tmp;
 
-	if (low_speed)		/* no isoc. here */
-	{
-		if (input_dir)
-		{
+	switch (speed) {
+	case USB_SPEED_LOW: 	/* INTR only */
+		if (is_input) {
 			tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L;
 			return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
-		}
-		else
-		{
+		} else {
 			tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L;
 			return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
 		}
+	case USB_SPEED_FULL:	/* ISOC or INTR */
+		if (isoc) {
+			tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
+			return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
+		} else {
+			tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
+			return (9107L + BW_HOST_DELAY + tmp);
+		}
+	case USB_SPEED_HIGH:	/* ISOC or INTR */
+		// FIXME adjust for input vs output
+		if (isoc)
+			tmp = HS_USECS (bytecount);
+		else
+			tmp = HS_USECS_ISO (bytecount);
+		return tmp;
+	default:
+		dbg ("bogus device speed!");
+		return -1;
 	}
-
-	/* for full-speed: */
-
-	if (!isoc)		/* Input or Output */
-	{
-		tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-		return (9107L + BW_HOST_DELAY + tmp);
-	} /* end not Isoc */
-
-	/* for isoc: */
-
-	tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-	return (((input_dir) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
 }
 
+
 /*
  * usb_check_bandwidth():
  *
@@ -285,7 +296,7 @@
 	unsigned int	pipe = urb->pipe;
 	long		bustime;
 
-	bustime = usb_calc_bus_time (usb_pipeslow(pipe), usb_pipein(pipe),
+	bustime = usb_calc_bus_time (dev->speed, usb_pipein(pipe),
 			usb_pipeisoc(pipe), usb_maxpacket(dev, pipe, usb_pipeout(pipe)));
 	if (usb_pipeisoc(pipe))
 		bustime = NS_TO_US(bustime) / urb->number_of_packets;
@@ -457,12 +468,11 @@
 	 */
 	down (&usb_bus_list_lock);
 	list_del(&bus->bus_list);
+	clear_bit(bus->busnum, busmap.busmap);
 	up (&usb_bus_list_lock);
 
 	usbdevfs_remove_bus(bus);
 
-	clear_bit(bus->busnum, busmap.busmap);
-
 	usb_bus_put(bus);
 }
 
@@ -939,6 +949,9 @@
 
 	usb_bus_get(bus);
 
+	if (!parent)
+		dev->devpath [0] = '0';
+
 	dev->bus = bus;
 	dev->parent = parent;
 	atomic_set(&dev->refcnt, 1);
@@ -1699,7 +1712,8 @@
 
 	*pdev = NULL;
 
-	info("USB disconnect on device %d", dev->devnum);
+	info("USB disconnect on device %s-%s address %d",
+			dev->bus->bus_name, dev->devpath, dev->devnum);
 
 	if (dev->actconfig) {
 		for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
@@ -2393,6 +2407,7 @@
 EXPORT_SYMBOL(usb_connect);
 EXPORT_SYMBOL(usb_disconnect);
 
+EXPORT_SYMBOL(usb_calc_bus_time);
 EXPORT_SYMBOL(usb_check_bandwidth);
 EXPORT_SYMBOL(usb_claim_bandwidth);
 EXPORT_SYMBOL(usb_release_bandwidth);
diff -urN linux-2.4.20-pre6/drivers/video/Config.in linux-2.4.20-pre7/drivers/video/Config.in
--- linux-2.4.20-pre6/drivers/video/Config.in	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/video/Config.in	Thu Sep 12 20:01:48 2002
@@ -150,6 +150,25 @@
 	 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
+	 if [ "$CONFIG_MIPS" = "y" ]; then
+	   tristate '  Epson SED1356 framebuffer support' CONFIG_FB_E1356
+	   if [ "$CONFIG_MIPS_PB1000" = "y" -a "$CONFIG_FB_E1356" != "n" ]; then
+	     bool '    Use CRT on Pb1000 (J65)' CONFIG_PB1000_CRT
+	     bool '    Use Compsite NTSC on Pb1000 (J63)' CONFIG_PB1000_NTSC
+	     bool '    Use TFT Panel on Pb1000 (J64)' CONFIG_PB1000_TFT
+	   fi
+           if [ "$CONFIG_MIPS_PB1500" = "y" -a "$CONFIG_FB_E1356" != "n" ]; then
+	     bool '    Use CRT on Pb1500 ' CONFIG_PB1500_CRT
+	     bool '    Use TFT Panel on Pb1500 ' CONFIG_PB1500_TFT
+           fi
+           if [ "$CONFIG_MIPS_PB1100" = "y" -a "$CONFIG_FB_E1356" != "n" ]; then
+	     bool '    Use CRT on Pb1100 ' CONFIG_PB1500_CRT
+	     bool '    Use TFT Panel on Pb1100 ' CONFIG_PB1500_TFT
+           fi
+           if [ "$CONFIG_MIPS_PB1100" = "y" ]; then
+	     bool '    Au1100 LCD Driver' CONFIG_FB_AU1100
+           fi
+	 fi
       fi
    fi
    if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
@@ -192,11 +211,9 @@
       tristate '  HD64461 Frame Buffer support' CONFIG_FB_HIT
    fi
    if [ "$CONFIG_DECSTATION" = "y" ]; then
-     if [ "$CONFIG_TC" = "y" ]; then
-       bool '  PMAG-BA TURBOchannel framebuffer support' CONFIG_FB_PMAG_BA
-       bool '  PMAGB-B TURBOchannel framebuffer spport' CONFIG_FB_PMAGB_B
-       bool '  Maxine (Personal DECstation) onboard framebuffer spport' CONFIG_FB_MAXINE
-     fi
+      dep_bool '  PMAG-BA TURBOchannel framebuffer support' CONFIG_FB_PMAG_BA $CONFIG_TC
+      dep_bool '  PMAGB-B TURBOchannel framebuffer support' CONFIG_FB_PMAGB_B $CONFIG_TC
+      dep_bool '  Maxine (Personal DECstation) onboard framebuffer support' CONFIG_FB_MAXINE
    fi
    if [ "$CONFIG_NINO" = "y" ]; then
       bool '  TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912
diff -urN linux-2.4.20-pre6/drivers/video/Makefile linux-2.4.20-pre7/drivers/video/Makefile
--- linux-2.4.20-pre6/drivers/video/Makefile	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/video/Makefile	Thu Sep 12 20:01:48 2002
@@ -85,6 +85,7 @@
 obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o
 obj-$(CONFIG_FB_MAXINE)           += maxinefb.o
 obj-$(CONFIG_FB_TX3912)           += tx3912fb.o
+obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
 
 subdir-$(CONFIG_STI_CONSOLE)      += sti
 ifeq ($(CONFIG_STI_CONSOLE),y)
@@ -96,7 +97,6 @@
 obj-y                             += sti/sti.o fbgen.o
 endif
 
-
 subdir-$(CONFIG_FB_MATROX)	  += matrox
 ifeq ($(CONFIG_FB_MATROX),y)
 obj-y				  += matrox/matrox.o
diff -urN linux-2.4.20-pre6/drivers/video/au1100fb.c linux-2.4.20-pre7/drivers/video/au1100fb.c
--- linux-2.4.20-pre6/drivers/video/au1100fb.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/video/au1100fb.c	Thu Sep 12 20:01:48 2002
@@ -0,0 +1,647 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1100 LCD Driver.
+ *
+ * Copyright 2002 MontaVista Software
+ * Author: MontaVista Software, Inc.
+ *		ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright 2002 Alchemy Semiconductor
+ * Author: Alchemy Semiconductor
+ *
+ * Based on:
+ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
+ *  Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU 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/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/init.h>
+#include <linux/pci.h>
+
+#include <asm/au1000.h>
+#include <asm/pb1100.h>
+#include "au1100fb.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>
+
+/* 
+ * Sanity check. If this is a new Au1100 based board, search for
+ * the PB1100 ifdefs to make sure you modify the code accordingly.
+ */
+#ifndef CONFIG_MIPS_PB1100
+error Unknown Au1100 board
+#endif
+
+#define CMAPSIZE 16
+
+static int my_lcd_index; /* default is zero */
+struct known_lcd_panels *p_lcd;
+AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
+
+struct au1100fb_info {
+	struct fb_info_gen gen;
+	unsigned long fb_virt_start;
+	unsigned long fb_size;
+	unsigned long fb_phys;
+	int mmaped;
+	int nohwcursor;
+
+	struct { unsigned red, green, blue, pad; } palette[256];
+
+#if defined(FBCON_HAS_CFB16)
+	u16 fbcon_cmap16[16];
+#endif
+};
+
+
+struct au1100fb_par {
+        struct fb_var_screeninfo var;
+	
+	int line_length;  // in bytes
+	int cmap_len;     // color-map length
+};
+
+
+static struct au1100fb_info fb_info;
+static struct au1100fb_par current_par;
+static struct display disp;
+
+int au1100fb_init(void);
+void au1100fb_setup(char *options, int *ints);
+static int au1100fb_mmap(struct fb_info *fb, struct file *file, 
+		struct vm_area_struct *vma);
+static int au1100_blank(int blank_mode, struct fb_info_gen *info);
+static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, int con, struct fb_info *info);
+
+void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
+
+static struct fb_ops au1100fb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	fbgen_get_fix,
+	fb_get_var:	fbgen_get_var,
+	fb_set_var:	fbgen_set_var,
+	fb_get_cmap:	fbgen_get_cmap,
+	fb_set_cmap:	fbgen_set_cmap,
+	fb_pan_display: fbgen_pan_display,
+        fb_ioctl:       au1100fb_ioctl,
+	fb_mmap:        au1100fb_mmap,
+};
+
+static void au1100_detect(void)
+{
+	/*
+	 *  This function should detect the current video mode settings 
+	 *  and store it as the default video mode
+	 */
+
+	/*
+	 * Yeh, well, we're not going to change any settings so we're
+	 * always stuck with the default ...
+	 */
+
+}
+
+static int au1100_encode_fix(struct fb_fix_screeninfo *fix, 
+		const void *_par, struct fb_info_gen *_info)
+{
+        struct au1100fb_info *info = (struct au1100fb_info *) _info;
+        struct au1100fb_par *par = (struct au1100fb_par *) _par;
+	struct fb_var_screeninfo *var = &par->var;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+	fix->smem_start = info->fb_phys;
+	fix->smem_len = info->fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+        fix->visual = (var->bits_per_pixel == 8) ?
+	       	FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;
+	fix->ywrapstep = 0;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->line_length = current_par.line_length;
+	return 0;
+}
+
+static void set_color_bitfields(struct fb_var_screeninfo *var)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		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;
+}
+
+static int au1100_decode_var(const struct fb_var_screeninfo *var, 
+		void *_par, struct fb_info_gen *_info)
+{
+
+	struct au1100fb_par *par = (struct au1100fb_par *)_par;
+
+	/*
+	 * Don't allow setting any of these yet: xres and yres don't
+	 * make sense for LCD panels.
+	 */
+	if (var->xres != p_lcd->xres ||
+	    var->yres != p_lcd->yres ||
+	    var->xres != p_lcd->xres ||
+	    var->yres != p_lcd->yres) {
+		return -EINVAL;
+	}
+	if(var->bits_per_pixel != p_lcd->bpp) {
+		return -EINVAL;
+	}
+
+	memset(par, 0, sizeof(struct au1100fb_par));
+	par->var = *var;
+	
+	/* FIXME */
+	switch (var->bits_per_pixel) {
+		case 8:
+			par->var.bits_per_pixel = 8;
+			break;
+		case 16:
+			par->var.bits_per_pixel = 16;
+			break;
+		default:
+			printk("color depth %d bpp not supported\n",
+					var->bits_per_pixel);
+			return -EINVAL;
+
+	}
+	set_color_bitfields(&par->var);
+	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
+	return 0;
+}
+
+static int au1100_encode_var(struct fb_var_screeninfo *var, 
+		const void *par, struct fb_info_gen *_info)
+{
+
+	*var = ((struct au1100fb_par *)par)->var;
+	return 0;
+}
+
+static void 
+au1100_get_par(void *_par, struct fb_info_gen *_info)
+{
+	*(struct au1100fb_par *)_par = current_par;
+}
+
+static void au1100_set_par(const void *par, struct fb_info_gen *info)
+{
+	/* nothing to do: we don't change any settings */
+}
+
+static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *info)
+{
+
+	struct au1100fb_info* i = (struct au1100fb_info*)info;
+
+	if (regno > 255)
+		return 1;
+   
+	*red    = i->palette[regno].red; 
+	*green  = i->palette[regno].green; 
+	*blue   = i->palette[regno].blue; 
+	*transp = 0;
+
+	return 0;
+}
+
+static int au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *info)
+{
+	struct au1100fb_info* i = (struct au1100fb_info *)info;
+	u32 rgbcol;
+
+	if (regno > 255)
+		return 1;
+
+	i->palette[regno].red    = red;
+	i->palette[regno].green  = green;
+	i->palette[regno].blue   = blue;
+   
+	switch(p_lcd->bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		red >>= 10;
+		green >>= 10;
+		blue >>= 10;
+		p_lcd_reg->lcd_pallettebase[regno] = (blue&0x1f) | 
+			((green&0x3f)<<5) | ((red&0x1f)<<11);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		i->fbcon_cmap16[regno] =
+			((red & 0xf800) >> 0) |
+			((green & 0xfc00) >> 5) |
+			((blue & 0xf800) >> 11);
+		break;
+#endif
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+
+static int  au1100_blank(int blank_mode, struct fb_info_gen *_info)
+{
+
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		/* turn on panel */
+		//printk("turn on panel\n");
+#ifdef CONFIG_MIPS_PB1100
+		p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+		au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, 
+			PB1100_G_CONTROL);
+		au_sync();
+#endif
+		break;
+
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+		/* turn off panel */
+		//printk("turn off panel\n");
+#ifdef CONFIG_MIPS_PB1100
+		p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
+		au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight, 
+			PB1100_G_CONTROL);
+		au_sync();
+#endif
+		break;
+	default: 
+		break;
+
+	}
+	return 0;
+}
+
+static void au1100_set_disp(const void *unused, struct display *disp,
+			 struct fb_info_gen *info)
+{
+	disp->screen_base = (char *)fb_info.fb_virt_start;
+
+	switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		if (fb_info.nohwcursor)
+			fbcon_cfb8.cursor = au1100_nocursor;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = fb_info.fbcon_cmap16;
+		if (fb_info.nohwcursor)
+			fbcon_cfb16.cursor = au1100_nocursor;
+		break;
+#endif
+	default:
+		disp->dispsw = &fbcon_dummy;
+		disp->dispsw_data = NULL;
+		break;
+	}
+}
+
+static int
+au1100fb_mmap(struct fb_info *_fb,
+	     struct file *file,
+	     struct vm_area_struct *vma)
+{
+	unsigned int len;
+	unsigned long start=0, off;
+	struct au1100fb_info *fb = (struct au1100fb_info *)_fb;
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+		return -EINVAL;
+	}
+    
+	start = fb_info.fb_phys & PAGE_MASK;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		return -EINVAL;
+	}
+
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+	pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+    
+	if (io_remap_page_range(vma->vm_start, off,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot)) {
+		return -EAGAIN;
+	}
+
+	fb->mmaped = 1;
+	return 0;
+}
+
+int au1100_pan_display(const struct fb_var_screeninfo *var,
+		       struct fb_info_gen *info)
+{
+	return 0;
+}
+
+static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+			  u_long arg, int con, struct fb_info *info)
+{
+	/* nothing to do yet */
+	return -EINVAL;
+}
+
+static struct fbgen_hwswitch au1100_switch = {
+	au1100_detect, 
+	au1100_encode_fix, 
+	au1100_decode_var, 
+	au1100_encode_var, 
+	au1100_get_par, 
+	au1100_set_par, 
+	au1100_getcolreg, 
+	au1100_setcolreg, 
+	au1100_pan_display, 
+	au1100_blank, 
+	au1100_set_disp
+};
+
+
+int au1100_setmode(void) 
+{
+	int words;
+
+	/* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/
+	switch (p_lcd->mode_control & LCD_CONTROL_SM)
+	{
+		case LCD_CONTROL_SM_0:
+		case LCD_CONTROL_SM_180:
+		words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;
+			break;
+		case LCD_CONTROL_SM_90:
+		case LCD_CONTROL_SM_270:
+			/* is this correct? */
+		words = (p_lcd->xres * p_lcd->bpp) / 8;
+			break;
+		default:
+			printk("mode_control reg not initialized\n");
+			return -EINVAL;
+	}
+
+	/*
+	 * Setup LCD controller
+	 */
+
+	p_lcd_reg->lcd_control = p_lcd->mode_control;
+	p_lcd_reg->lcd_intstatus = 0;
+	p_lcd_reg->lcd_intenable = 0;
+	p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;
+	p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
+	p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
+	p_lcd_reg->lcd_words = words - 1;
+	p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
+
+#ifdef CONFIG_MIPS_PB1100
+	/* turn on panel */
+	au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, 
+			PB1100_G_CONTROL);
+	p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
+#endif
+
+	return 0;
+}
+
+
+int __init au1100fb_init(void)
+{
+	uint32 sys_clksrc;
+	unsigned long page;
+
+	/*
+	* Get the panel information/display mode and update the registry
+	*/
+	p_lcd = &panels[my_lcd_index];
+
+	switch (p_lcd->mode_control & LCD_CONTROL_SM)
+	{
+		case LCD_CONTROL_SM_0:
+		case LCD_CONTROL_SM_180:
+		p_lcd->xres = 
+			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
+		p_lcd->yres = 
+			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
+			break;
+		case LCD_CONTROL_SM_90:
+		case LCD_CONTROL_SM_270:
+		p_lcd->yres = 
+			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
+		p_lcd->xres = 
+			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
+			break;
+	}
+
+	/*
+	 * Panel dimensions x bpp must be divisible by 32
+	 */
+	if (((p_lcd->yres * p_lcd->bpp) % 32) != 0) 
+		printk("VERT %% 32\n");
+	if (((p_lcd->xres * p_lcd->bpp) % 32) != 0) 
+		printk("HORZ %% 32\n");
+
+	/*
+	 * Allocate LCD framebuffer from system memory
+	 */
+	fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
+	
+	current_par.var.xres = p_lcd->xres;
+	current_par.var.xres_virtual = p_lcd->xres;
+	current_par.var.yres = p_lcd->yres;
+	current_par.var.yres_virtual = p_lcd->yres;
+	current_par.var.bits_per_pixel = p_lcd->bpp;
+
+	/* FIX!!! only works for 8/16 bpp */
+	current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
+	fb_info.fb_virt_start = (unsigned long )
+		__get_free_pages(GFP_ATOMIC | GFP_DMA, 
+				get_order(fb_info.fb_size + 0x1000));
+	if (!fb_info.fb_virt_start) {
+		printk("Unable to allocate fb memory\n");
+		return -ENOMEM;
+	}
+	fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
+
+	/*
+	 * Set page reserved so that mmap will work. This is necessary
+	 * since we'll be remapping normal memory.
+	 */
+	for (page = fb_info.fb_virt_start;
+	     page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size); 
+	     page += PAGE_SIZE) {
+		SetPageReserved(virt_to_page(page));
+	}
+
+	memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
+
+	/* set freqctrl now to allow more time to stabilize */
+	/* zero-out out LCD bits */
+	sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0; 
+	sys_clksrc |= p_lcd->mode_toyclksrc;
+	au_writel(sys_clksrc, SYS_CLKSRC);
+
+	/* FIXME add check to make sure auxpll is what is expected! */
+	au1100_setmode();
+
+	fb_info.gen.parsize = sizeof(struct au1100fb_par);
+	fb_info.gen.fbhw = &au1100_switch;
+
+	strcpy(fb_info.gen.info.modename, "Au1100 LCD");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+
+	fb_info.gen.info.fbops = &au1100fb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* This should give a reasonable default video mode */
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	fbgen_install_cmap(0, &fb_info.gen);
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		return -EINVAL;
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", 
+			GET_FB_IDX(fb_info.gen.info.node), 
+			fb_info.gen.info.modename);
+
+	/* uncomment this if your driver cannot be unloaded */
+	/* MOD_INC_USE_COUNT; */
+	return 0;
+}
+
+
+void au1100fb_cleanup(struct fb_info *info)
+{
+	unregister_framebuffer(info);
+}
+
+
+void au1100fb_setup(char *options, int *ints)
+{
+	char* this_opt;
+	int i;
+	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
+
+    
+	if (!options || !*options)
+		return;
+
+	for(this_opt=strtok(options, ","); this_opt;
+	    this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "panel:", 6)) {
+			/* Get the panel name, everything else if fixed */
+			for (i=0; i<num_panels; i++) {
+				if (!strncmp(this_opt+6, panels[i].panel_name, 
+							strlen(this_opt))) {
+					my_lcd_index = i;
+					break;
+				}
+			}
+		}
+		else if (!strncmp(this_opt, "nohwcursor", 10)) {
+			printk("nohwcursor\n");
+			fb_info.nohwcursor = 1;
+		}
+	} 
+}
+
+
+
+#ifdef MODULE
+MODULE_LICENSE("GPL");
+int init_module(void)
+{
+	return au1100fb_init();
+}
+
+void cleanup_module(void)
+{
+	au1100fb_cleanup(void);
+}
+
+MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
+MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
+#endif /* MODULE */
diff -urN linux-2.4.20-pre6/drivers/video/au1100fb.h linux-2.4.20-pre7/drivers/video/au1100fb.h
--- linux-2.4.20-pre6/drivers/video/au1100fb.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/video/au1100fb.h	Thu Sep 12 20:01:48 2002
@@ -0,0 +1,381 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Hardware definitions for the Au1100 LCD controller
+ *
+ * Copyright 2002 MontaVista Software
+ * Copyright 2002 Alchemy Semiconductor
+ * Author:	Alchemy Semiconductor, MontaVista Software
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU 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 _AU1100LCD_H
+#define _AU1100LCD_H
+
+/********************************************************************/
+#define uint32 unsigned long
+typedef volatile struct
+{
+	uint32	lcd_control;
+	uint32	lcd_intstatus;
+	uint32	lcd_intenable;
+	uint32	lcd_horztiming;
+	uint32	lcd_verttiming;
+	uint32	lcd_clkcontrol;
+	uint32	lcd_dmaaddr0;
+	uint32	lcd_dmaaddr1;
+	uint32	lcd_words;
+	uint32	lcd_pwmdiv;
+	uint32	lcd_pwmhi;
+	uint32	reserved[(0x0400-0x002C)/4];
+	uint32	lcd_pallettebase[256];
+
+} AU1100_LCD;
+
+/********************************************************************/
+
+#define AU1100_LCD_ADDR		0xB5000000
+
+/*
+ * Register bit definitions
+ */
+
+/* lcd_control */
+#define LCD_CONTROL_SBPPF		(7<<18)
+#define LCD_CONTROL_SBPPF_655	(0<<18)
+#define LCD_CONTROL_SBPPF_565	(1<<18)
+#define LCD_CONTROL_SBPPF_556	(2<<18)
+#define LCD_CONTROL_SBPPF_1555	(3<<18)
+#define LCD_CONTROL_SBPPF_5551	(4<<18)
+#define LCD_CONTROL_WP			(1<<17)
+#define LCD_CONTROL_WD			(1<<16)
+#define LCD_CONTROL_C			(1<<15)
+#define LCD_CONTROL_SM			(3<<13)
+#define LCD_CONTROL_SM_0		(0<<13)
+#define LCD_CONTROL_SM_90		(1<<13)
+#define LCD_CONTROL_SM_180		(2<<13)
+#define LCD_CONTROL_SM_270		(3<<13)
+#define LCD_CONTROL_DB			(1<<12)
+#define LCD_CONTROL_CCO			(1<<11)
+#define LCD_CONTROL_DP			(1<<10)
+#define LCD_CONTROL_PO			(3<<8)
+#define LCD_CONTROL_PO_00		(0<<8)
+#define LCD_CONTROL_PO_01		(1<<8)
+#define LCD_CONTROL_PO_10		(2<<8)
+#define LCD_CONTROL_PO_11		(3<<8)
+#define LCD_CONTROL_MPI			(1<<7)
+#define LCD_CONTROL_PT			(1<<6)
+#define LCD_CONTROL_PC			(1<<5)
+#define LCD_CONTROL_BPP			(7<<1)
+#define LCD_CONTROL_BPP_1		(0<<1)
+#define LCD_CONTROL_BPP_2		(1<<1)
+#define LCD_CONTROL_BPP_4		(2<<1)
+#define LCD_CONTROL_BPP_8		(3<<1)
+#define LCD_CONTROL_BPP_12		(4<<1)
+#define LCD_CONTROL_BPP_16		(5<<1)
+#define LCD_CONTROL_GO			(1<<0)
+
+/* lcd_intstatus, lcd_intenable */
+#define LCD_INT_SD				(1<<7)
+#define LCD_INT_OF				(1<<6)
+#define LCD_INT_UF				(1<<5)
+#define LCD_INT_SA				(1<<3)
+#define LCD_INT_SS				(1<<2)
+#define LCD_INT_S1				(1<<1)
+#define LCD_INT_S0				(1<<0)
+
+/* lcd_horztiming */
+#define LCD_HORZTIMING_HN2		(255<<24)
+#define LCD_HORZTIMING_HN2_N(N)	(((N)-1)<<24)
+#define LCD_HORZTIMING_HN1		(255<<16)
+#define LCD_HORZTIMING_HN1_N(N)	(((N)-1)<<16)
+#define LCD_HORZTIMING_HPW		(63<<10)
+#define LCD_HORZTIMING_HPW_N(N)	(((N)-1)<<10)
+#define LCD_HORZTIMING_PPL		(1023<<0)
+#define LCD_HORZTIMING_PPL_N(N)	(((N)-1)<<0)
+
+/* lcd_verttiming */
+#define LCD_VERTTIMING_VN2		(255<<24)
+#define LCD_VERTTIMING_VN2_N(N)	(((N)-1)<<24)
+#define LCD_VERTTIMING_VN1		(255<<16)
+#define LCD_VERTTIMING_VN1_N(N)	(((N)-1)<<16)
+#define LCD_VERTTIMING_VPW		(63<<10)
+#define LCD_VERTTIMING_VPW_N(N)	(((N)-1)<<10)
+#define LCD_VERTTIMING_LPP		(1023<<0)
+#define LCD_VERTTIMING_LPP_N(N)	(((N)-1)<<0)
+
+/* lcd_clkcontrol */
+#define LCD_CLKCONTROL_IB		(1<<18)
+#define LCD_CLKCONTROL_IC		(1<<17)
+#define LCD_CLKCONTROL_IH		(1<<16)
+#define LCD_CLKCONTROL_IV		(1<<15)
+#define LCD_CLKCONTROL_BF		(31<<10)
+#define LCD_CLKCONTROL_BF_N(N)	(((N)-1)<<10)
+#define LCD_CLKCONTROL_PCD		(1023<<0)
+#define LCD_CLKCONTROL_PCD_N(N)	((N)<<0)
+
+/* lcd_pwmdiv */
+#define LCD_PWMDIV_EN			(1<<12)
+#define LCD_PWMDIV_PWMDIV		(2047<<0)
+#define LCD_PWMDIV_PWMDIV_N(N)	(((N)-1)<<0)
+
+/* lcd_pwmhi */
+#define LCD_PWMHI_PWMHI1		(2047<<12)
+#define LCD_PWMHI_PWMHI1_N(N)	((N)<<12)
+#define LCD_PWMHI_PWMHI0		(2047<<0)
+#define LCD_PWMHI_PWMHI0_N(N)	((N)<<0)
+
+/* lcd_pallettebase - MONOCHROME */
+#define LCD_PALLETTE_MONO_MI		(15<<0)
+#define LCD_PALLETTE_MONO_MI_N(N)	((N)<<0)
+
+/* lcd_pallettebase - COLOR */
+#define LCD_PALLETTE_COLOR_BI		(15<<8)
+#define LCD_PALLETTE_COLOR_BI_N(N)	((N)<<8)
+#define LCD_PALLETTE_COLOR_GI		(15<<4)
+#define LCD_PALLETTE_COLOR_GI_N(N)	((N)<<4)
+#define LCD_PALLETTE_COLOR_RI		(15<<0)
+#define LCD_PALLETTE_COLOR_RI_N(N)	((N)<<0)
+
+/* lcd_palletebase - COLOR TFT PALLETIZED */
+#define LCD_PALLETTE_TFT_DC			(65535<<0)
+#define LCD_PALLETTE_TFT_DC_N(N)	((N)<<0)
+
+/********************************************************************/
+
+struct known_lcd_panels
+{
+	uint32 xres;
+	uint32 yres;
+	uint32 bpp;
+	unsigned char  panel_name[256];
+	uint32 mode_control;
+	uint32 mode_horztiming;
+	uint32 mode_verttiming;
+	uint32 mode_clkcontrol;
+	uint32 mode_pwmdiv;
+	uint32 mode_pwmhi;
+	uint32 mode_toyclksrc;
+	uint32 mode_backlight;
+
+};
+
+#if defined(__BIG_ENDIAN)
+#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
+#else
+#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
+#endif
+
+/*
+ * The fb driver assumes that AUX PLL is at 48MHz.  That can
+ * cover up to 800x600 resolution; if you need higher resolution,
+ * you should modify the driver as needed, not just this structure.
+ */
+struct known_lcd_panels panels[] =
+{
+	{ /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
+		320, /* xres */
+		240, /* yres */
+		16,  /* bpp  */
+		
+		"Sharp_320x240_16",
+		/* mode_control */
+		( LCD_CONTROL_SBPPF_565
+		/*LCD_CONTROL_WP*/
+		/*LCD_CONTROL_WD*/
+		| LCD_CONTROL_C
+		| LCD_CONTROL_SM_0
+		/*LCD_CONTROL_DB*/
+		/*LCD_CONTROL_CCO*/
+		/*LCD_CONTROL_DP*/
+		| LCD_DEFAULT_PIX_FORMAT
+		/*LCD_CONTROL_MPI*/
+		| LCD_CONTROL_PT
+		| LCD_CONTROL_PC
+		| LCD_CONTROL_BPP_16 ),
+
+		/* mode_horztiming */
+		( LCD_HORZTIMING_HN2_N(8)
+		| LCD_HORZTIMING_HN1_N(60)
+		| LCD_HORZTIMING_HPW_N(12)
+		| LCD_HORZTIMING_PPL_N(320) ),
+
+		/* mode_verttiming */
+		( LCD_VERTTIMING_VN2_N(5)
+		| LCD_VERTTIMING_VN1_N(17)
+		| LCD_VERTTIMING_VPW_N(1)
+		| LCD_VERTTIMING_LPP_N(240) ),
+
+		/* mode_clkcontrol */
+		( 0
+		/*LCD_CLKCONTROL_IB*/
+		/*LCD_CLKCONTROL_IC*/
+		/*LCD_CLKCONTROL_IH*/
+		/*LCD_CLKCONTROL_IV*/
+		| LCD_CLKCONTROL_PCD_N(1) ),
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (1<<5)),
+
+		/* mode_backlight */
+		6
+	},
+
+	{ /* 1: Pb1100 LCDC 640x480 TFT panel */
+		640, /* xres */
+		480, /* yres */
+		16,  /* bpp  */
+
+		"Generic_640x480_16",
+
+		/* mode_control */
+		0x004806a | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x3434d67f,
+
+		/* mode_verttiming */
+		0x0e0e39df,
+
+		/* mode_clkcontrol */
+		( 0
+		/*LCD_CLKCONTROL_IB*/
+		/*LCD_CLKCONTROL_IC*/
+		/*LCD_CLKCONTROL_IH*/
+		/*LCD_CLKCONTROL_IV*/
+		| LCD_CLKCONTROL_PCD_N(1) ),
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+
+	{ /* 2: Pb1100 LCDB 640x480 PrimeView TFT panel */
+		640, /* xres */
+		480, /* yres */
+		16,  /* bpp  */
+
+		"PrimeView_640x480_16",
+
+		/* mode_control */
+		0x0004886a | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x0e4bfe7f,
+
+		/* mode_verttiming */
+		0x210805df,
+
+		/* mode_clkcontrol */
+		0x00038001,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+
+	{ /* 3: Pb1100 800x600x16bpp NEON CRT */
+		800, /* xres */
+		600, /* yres */
+		16,  /* bpp */
+
+		"NEON_800x600_16",
+
+		/* mode_control */
+		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x005AFF1F,
+
+		/* mode_verttiming */
+		0x16000E57,
+
+		/* mode_clkcontrol */
+		0x00020000,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+
+	{ /* 4: Pb1100 640x480x16bpp NEON CRT */
+		640, /* xres */
+		480, /* yres */
+		16,  /* bpp */
+
+		"NEON_640x480_16",
+
+		/* mode_control */
+		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
+
+		/* mode_horztiming */
+		0x0052E27F,
+
+		/* mode_verttiming */
+		0x18000DDF,
+
+		/* mode_clkcontrol */
+		0x00020000,
+
+		/* mode_pwmdiv */
+		0,
+
+		/* mode_pwmhi */
+		0,
+
+		/* mode_toyclksrc */
+		((1<<7) | (1<<6) | (0<<5)),
+
+		/* mode_backlight */
+		7
+	},
+};
+#endif /* _AU1100LCD_H */
diff -urN linux-2.4.20-pre6/drivers/video/epson1356fb.c linux-2.4.20-pre7/drivers/video/epson1356fb.c
--- linux-2.4.20-pre6/drivers/video/epson1356fb.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/video/epson1356fb.c	Thu Sep 12 20:01:48 2002
@@ -0,0 +1,3158 @@
+/*
+ *      epson1356fb.c  --  Epson SED1356 Framebuffer Driver
+ *
+ * Copyright 2001, 2002 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.
+ *
+ * 
+ * TODO:
+ *
+ *  Revision history
+ *    03.12.2001  0.1   Initial release
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.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/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/nvram.h>
+#include <linux/kd.h>
+#include <linux/vt_kern.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/timer.h>
+#include <linux/pagemap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.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 <linux/spinlock.h>
+
+#include <linux/e1356fb.h>
+
+#ifdef CONFIG_MIPS_AU1000
+#include <asm/au1000.h>
+#endif
+
+#define E1356FB_DEBUG 1
+#undef E1356FB_VERBOSE_DEBUG
+#undef SHADOW_FRAME_BUFFER
+#include "epson1356fb.h"
+
+static char *options;
+MODULE_PARM(options, "s");
+
+/*
+ *  Frame buffer device API
+ */
+static int e1356fb_open(struct fb_info *fb, int user);
+static int e1356fb_release(struct fb_info *fb, int user);
+static int e1356fb_get_fix(struct fb_fix_screeninfo* fix, 
+			   int con,
+			   struct fb_info* fb);
+static int e1356fb_get_var(struct fb_var_screeninfo* var, 
+			   int con,
+			   struct fb_info* fb);
+static int e1356fb_set_var(struct fb_var_screeninfo* var,
+			   int con,
+			   struct fb_info* fb);
+static int e1356fb_pan_display(struct fb_var_screeninfo* var, 
+			       int con,
+			       struct fb_info* fb);
+static int e1356fb_get_cmap(struct fb_cmap *cmap, 
+			    int kspc, 
+			    int con,
+			    struct fb_info* info);
+static int e1356fb_set_cmap(struct fb_cmap* cmap, 
+			    int kspc, 
+			    int con,
+			    struct fb_info* info);
+static int e1356fb_ioctl(struct inode* inode, 
+			 struct file* file, 
+			 u_int cmd,
+			 u_long arg, 
+			 int con, 
+			 struct fb_info* info);
+static int e1356fb_mmap(struct fb_info *info,
+			struct file *file,
+			struct vm_area_struct *vma);
+
+/*
+ *  Interface to the low level console driver
+ */
+static int  e1356fb_switch_con(int con, 
+			       struct fb_info* fb);
+static int  e1356fb_updatevar(int con, 
+			      struct fb_info* fb);
+static void e1356fb_blank(int blank, 
+			  struct fb_info* fb);
+
+/*
+ *  Internal routines
+ */
+static void e1356fb_set_par(const struct e1356fb_par* par,
+			    struct fb_info_e1356* 
+			    info);
+static int  e1356fb_var_to_par(const struct fb_var_screeninfo *var,
+			       struct e1356fb_par* par,
+			       const struct fb_info_e1356* info);
+static int  e1356fb_par_to_var(struct fb_var_screeninfo* var,
+			       struct e1356fb_par* par,
+			       const struct fb_info_e1356* info);
+static int  e1356fb_encode_fix(struct fb_fix_screeninfo* fix,
+			       const struct e1356fb_par* par,
+			       const struct fb_info_e1356* info);
+static void e1356fb_set_dispsw(struct display* disp, 
+			       struct fb_info_e1356* info,
+			       int bpp, 
+			       int accel);
+static int  e1356fb_getcolreg(u_int regno,
+			      u_int* red, 
+			      u_int* green, 
+			      u_int* blue,
+			      u_int* transp, 
+			      struct fb_info* fb);
+static int  e1356fb_setcolreg(u_int regno, 
+			      u_int red, 
+			      u_int green, 
+			      u_int blue,
+			      u_int transp, 
+			      struct fb_info* fb);
+static void  e1356fb_install_cmap(struct display *d, 
+				  struct fb_info *info);
+
+static void e1356fb_hwcursor_init(struct fb_info_e1356* info);
+static void e1356fb_createcursorshape(struct display* p);
+static void e1356fb_createcursor(struct display * p);  
+
+/*
+ * do_xxx: Hardware-specific functions
+ */
+static void  do_pan_var(struct fb_var_screeninfo* var,
+			struct fb_info_e1356* i);
+static void  do_flashcursor(unsigned long ptr);
+static void  doBlt_Move(const struct e1356fb_par* par,
+			struct fb_info_e1356* i,
+			blt_info_t* blt);
+static void  doBlt_SolidFill(const struct e1356fb_par* par,
+			     struct fb_info_e1356* i,
+			     blt_info_t* blt);
+
+/*
+ *  Interface used by the world
+ */
+int e1356fb_init(void);
+void e1356fb_setup(char *options, int *ints);
+
+static int currcon = 0;
+
+static struct fb_ops e1356fb_ops = {
+	owner:	THIS_MODULE,
+	fb_open:        e1356fb_open,
+	fb_release:     e1356fb_release,
+	fb_get_fix:	e1356fb_get_fix,
+	fb_get_var:	e1356fb_get_var,
+	fb_set_var:	e1356fb_set_var,
+	fb_get_cmap:    e1356fb_get_cmap,
+	fb_set_cmap:    e1356fb_set_cmap,
+	fb_pan_display: e1356fb_pan_display,
+	fb_ioctl:	e1356fb_ioctl,
+	fb_mmap:        e1356fb_mmap,
+};
+
+#define PCI_VENDOR_ID_EPSON         0x10f4
+#define PCI_DEVICE_ID_EPSON_SDU1356 0x1300
+
+
+static struct fb_info_e1356 fb_info;
+static struct e1356fb_fix boot_fix; // boot options
+static struct e1356fb_par boot_par; // boot options
+
+static int e1356_remap_page_range(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot);
+
+
+/* ------------------------------------------------------------------------- 
+ *                      Hardware-specific funcions
+ * ------------------------------------------------------------------------- */
+
+/*
+ * The SED1356 has only a 16-bit wide data bus, so some embedded
+ * implementations with 32-bit CPU's (Alchemy Pb1000) may not
+ * correctly emulate a 32-bit write to the framebuffer by splitting
+ * the write into two seperate 16-bit writes. So it is safest to
+ * only do byte or half-word writes to the fb. This routine assumes
+ * fbaddr is atleast aligned on a half-word boundary.
+ */
+static inline void
+fbfill(u16* fbaddr, u8 val, int size)
+{
+	u16 valw = (u16)val | ((u16)val << 8);
+	for ( ; size >= 2; size -= 2)
+		writew(valw, fbaddr++);
+	if (size)
+		writeb(val, (u8*)fbaddr);
+}
+
+static inline int
+e1356_wait_bitclr(u8* reg, u8 bit, int timeout)
+{
+	while (readb(reg) & bit) {
+		udelay(10);
+		if (!--timeout)
+			break;
+	}
+	return timeout;
+}
+
+static inline int
+e1356_wait_bitset(u8* reg, u8 bit, int timeout)
+{
+	while (!(readb(reg) & bit)) {
+		udelay(10);
+		if (!--timeout)
+			break;
+	}
+	return timeout;
+}
+
+
+static struct fb_videomode panel_modedb[] = {
+	{
+		/* 320x240 @ 109 Hz, 33.3 kHz hsync */
+		NULL, 109, 320, 240, KHZ2PICOS(MAX_PIXCLOCK/3),
+		16, 16, 32, 24, 48, 8,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 640x480 @ 84 Hz, 48.1 kHz hsync */
+		NULL, 84, 640, 480, KHZ2PICOS(MAX_PIXCLOCK/1),
+		96, 32, 32, 48, 64, 8,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 800x600 @ 76 Hz, 46.3 kHz hsync */
+		NULL, 76, 800, 600, KHZ2PICOS(MAX_PIXCLOCK/1),
+		32, 10, 1, 1, 22, 1,
+		0, FB_VMODE_NONINTERLACED
+	}
+};
+static struct fb_videomode crt_modedb[] = {
+	{
+		/* 320x240 @ 84 Hz, 31.25 kHz hsync */
+		NULL, 84, 320, 240, KHZ2PICOS(MAX_PIXCLOCK/2),
+		128, 128, 60, 60, 64, 8,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 320x240 @ 109 Hz, 33.3 kHz hsync */
+		NULL, 109, 320, 240, KHZ2PICOS(MAX_PIXCLOCK/3),
+		16, 16, 32, 24, 48, 8,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 512x384 @ 77 Hz, 31.25 kHz hsync */
+		NULL, 77, 512, 384, KHZ2PICOS(MAX_PIXCLOCK/2),
+		48, 16, 16, 1, 64, 3,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 640x400 @ 88 Hz, 43.1 kHz hsync */
+		NULL, 88, 640, 400, KHZ2PICOS(MAX_PIXCLOCK/1),
+		128, 96, 32, 48, 64, 8,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 640x480 @ 84 Hz, 48.1 kHz hsync */
+		NULL, 84, 640, 480, KHZ2PICOS(MAX_PIXCLOCK/1),
+		96, 32, 32, 48, 64, 8,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 768x576 @ 62 Hz, 38.5 kHz hsync */
+		NULL, 62, 768, 576, KHZ2PICOS(MAX_PIXCLOCK/1),
+		144, 16, 28, 6, 112, 4,
+		0, FB_VMODE_NONINTERLACED
+	}, {
+		/* 800x600 @ 60 Hz, 37.9 kHz hsync */
+		NULL, 60, 800, 600, KHZ2PICOS(MAX_PIXCLOCK/1),
+		88, 40, 23, 1, 128, 4,
+		FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+		FB_VMODE_NONINTERLACED
+	}
+};
+
+static struct fb_videomode ntsc_modedb[] = {
+	{
+		/* 640x480 @ 62 Hz, requires flicker filter */
+		//NULL, 62, 640, 480, 34921, 213, 57, 20, 2, 0, 0,
+		NULL, 62, 640, 480, KHZ2PICOS(2*NTSC_PIXCLOCK),
+		200, 70, 15, 7, 0, 0,
+		FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+	}
+};
+static struct fb_videomode pal_modedb[] = {
+	{
+		/* 640x480 @ 56 Hz, requires flicker filter */
+		NULL, 56, 640, 480, KHZ2PICOS(2*PAL_PIXCLOCK),
+		350, 145, 49, 23, 0, 0,
+		FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+	}
+};
+
+
+static inline void
+fb_videomode_to_var(struct fb_videomode* mode,
+		    struct fb_var_screeninfo*var)
+{
+	var->xres = mode->xres;
+	var->yres = mode->yres;
+	var->pixclock = mode->pixclock;
+	var->left_margin = mode->left_margin;
+	var->right_margin = mode->right_margin;
+	var->upper_margin = mode->upper_margin;
+	var->lower_margin = mode->lower_margin;
+	var->hsync_len = mode->hsync_len;
+	var->vsync_len = mode->vsync_len;
+	var->sync = mode->sync;
+	var->vmode = mode->vmode;
+}
+
+
+static int
+e1356fb_get_mode(const struct fb_info_e1356 *info,
+		 int xres,
+		 int yres,
+		 struct fb_videomode ** modedb,
+		 struct fb_videomode ** mode)
+{
+	struct fb_videomode * ret;
+	int i, dbsize;
+
+	if (IS_PANEL(info->fix.disp_type)) {
+		ret = panel_modedb;
+		dbsize = sizeof(panel_modedb)/sizeof(struct fb_videomode);
+	} else if (info->fix.disp_type == DISP_TYPE_CRT) {
+		ret = crt_modedb;
+		dbsize = sizeof(crt_modedb)/sizeof(struct fb_videomode);
+	} else if (info->fix.disp_type == DISP_TYPE_NTSC) {
+		ret = ntsc_modedb;
+		dbsize = sizeof(ntsc_modedb)/sizeof(struct fb_videomode);
+	} else {
+		ret = pal_modedb;
+		dbsize = sizeof(pal_modedb)/sizeof(struct fb_videomode);
+	}
+	
+	if (modedb)
+		*modedb = ret;
+	for (i=0; i<dbsize; i++) {
+		if (xres == ret[i].xres && yres == ret[i].yres) {
+			*mode = &ret[i];
+			break;
+		}
+	}
+	if (i == dbsize)
+		return -EINVAL;
+	return dbsize;
+}
+
+
+
+#ifdef E1356FB_VERBOSE_DEBUG
+static void
+dump_par(const struct e1356fb_par* par)
+{
+	DPRINTK("width:       %d\n", par->width);
+	DPRINTK("height:      %d\n", par->height);
+	DPRINTK("width_virt:  %d\n", par->width_virt);
+	DPRINTK("height_virt: %d\n", par->height_virt);
+	DPRINTK("bpp:         %d\n", par->bpp);
+	DPRINTK("pixclock:    %d\n", par->ipclk.pixclk);
+	DPRINTK("horiz_ndp:   %d\n", par->horiz_ndp);
+	DPRINTK("vert_ndp:    %d\n", par->vert_ndp);
+	DPRINTK("hsync_pol:   %d\n", par->hsync_pol);
+	DPRINTK("hsync_start: %d\n", par->hsync_start);
+	DPRINTK("hsync_width: %d\n", par->hsync_width);
+	DPRINTK("vsync_pol:   %d\n", par->vsync_pol);
+	DPRINTK("vsync_start: %d\n", par->vsync_start);
+	DPRINTK("vsync_width: %d\n", par->vsync_width);
+	DPRINTK("cmap_len:    %d\n", par->cmap_len);
+}
+
+static void
+dump_display_regs(reg_dispcfg_t* dispcfg, reg_dispmode_t* dispmode)
+{
+	DPRINTK("hdw:            0x%02x\n", readb(&dispcfg->hdw));
+	DPRINTK("hndp:           0x%02x\n", readb(&dispcfg->hndp));
+	DPRINTK("hsync_start:    0x%02x\n", readb(&dispcfg->hsync_start));
+	DPRINTK("hsync_pulse:    0x%02x\n", readb(&dispcfg->hsync_pulse));
+	DPRINTK("vdh0:           0x%02x\n", readb(&dispcfg->vdh0));
+	DPRINTK("vdh1:           0x%02x\n", readb(&dispcfg->vdh1));
+	DPRINTK("vndp:           0x%02x\n", readb(&dispcfg->vndp));
+	DPRINTK("vsync_start:    0x%02x\n", readb(&dispcfg->vsync_start));
+	DPRINTK("vsync_pulse:    0x%02x\n", readb(&dispcfg->vsync_pulse));
+	DPRINTK("tv_output_ctrl: 0x%02x\n\n", readb(&dispcfg->tv_output_ctrl));
+
+	DPRINTK("disp_mode:        0x%02x\n", readb(&dispmode->disp_mode));
+	DPRINTK("lcd_misc:         0x%02x\n", readb(&dispmode->lcd_misc));
+	DPRINTK("start_addr0:      0x%02x\n", readb(&dispmode->start_addr0));
+	DPRINTK("start_addr1:      0x%02x\n", readb(&dispmode->start_addr1));
+	DPRINTK("start_addr2:      0x%02x\n", readb(&dispmode->start_addr2));
+	DPRINTK("mem_addr_offset0: 0x%02x\n", readb(&dispmode->mem_addr_offset0));
+	DPRINTK("mem_addr_offset1: 0x%02x\n", readb(&dispmode->mem_addr_offset1));
+	DPRINTK("pixel_panning:    0x%02x\n", readb(&dispmode->pixel_panning));
+	DPRINTK("fifo_high_thresh: 0x%02x\n", readb(&dispmode->fifo_high_thresh));
+	DPRINTK("fifo_low_thresh:  0x%02x\n", readb(&dispmode->fifo_low_thresh));
+}
+
+static void
+dump_fb(u8* base, int len)
+{
+	int i;
+	DPRINTK("FB memory dump, start 0x%p, len %d", base, len);
+	for (i=0; i<len; i++) {
+		if (!(i%16))
+			printk("\n%p: %02x ", &base[i], readb(&base[i]));
+		else
+			printk("%02x ", readb(&base[i]));
+	}
+	printk("\n");
+}
+
+#endif // E1356FB_VERBOSE_DEBUG
+
+
+
+// Input:  ipclk->clksrc, ipclk->pixclk_d
+// Output: ipclk->pixclk, ipclk->error, and ipclk->divisor
+static int
+get_nearest_pixclk_div(pixclock_info_t* ipclk, int x2)
+{
+	int pixclk_d = ipclk->pixclk_d;
+	int clksrc = ipclk->clksrc;
+
+	if (x2) clksrc *= 2;
+
+	if (clksrc < (3*pixclk_d+1)/2)
+		ipclk->divisor = 1;
+	else if (clksrc < (5*pixclk_d+1)/2)
+		ipclk->divisor = 2;
+	else if (clksrc < (7*pixclk_d+1)/2)
+		ipclk->divisor = 3;
+	else if (clksrc < (9*pixclk_d+1)/2)
+		ipclk->divisor = 4;
+	else
+		return -ENXIO;
+
+	ipclk->pixclk = clksrc / ipclk->divisor;
+	ipclk->error = (100*(pixclk_d - ipclk->pixclk)) / pixclk_d;
+	return 0;
+}
+
+static int
+e1356_calc_pixclock(const struct fb_info_e1356 *info,
+		    pixclock_info_t* ipclk)
+{
+	int src_sel=-1, flicker_mult=0;
+	pixclock_info_t test, ret;
+    
+	if (ipclk->pixclk > info->max_pixclock)
+		return -ENXIO;
+
+	test.pixclk_d = ipclk->pixclk_d;
+	ret.error = 100;
+	
+	if (IS_TV(info->fix.disp_type) &&
+	    (info->fix.tv_filt & TV_FILT_FLICKER))
+		flicker_mult = 0x80;
+	
+	test.clksrc = info->fix.busclk;
+	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
+	    abs(test.error) < abs(ret.error)) {
+		ret = test;
+		src_sel = 0x01;
+	}
+
+	test.clksrc = info->fix.mclk;
+	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
+	    abs(test.error) < abs(ret.error)) {
+		ret = test;
+		src_sel = 0x03;
+	}
+
+	test.clksrc = info->fix.clki;
+	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
+	    abs(test.error) < abs(ret.error)) {
+		ret = test;
+		src_sel = 0x00;
+	}
+
+	test.clksrc = info->fix.clki2;
+	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
+	    abs(test.error) < abs(ret.error)) {
+		ret = test;
+		src_sel = 0x02;
+	}
+
+	if (ret.error > MAX_PCLK_ERROR_LOWER ||
+	    ret.error < MAX_PCLK_ERROR_HIGHER)
+		return -ENXIO;
+    
+	ret.pixclk_bits = flicker_mult | ((ret.divisor-1)<<4) | src_sel;
+	*ipclk = ret;
+	return 0;
+}
+
+static inline int
+e1356_engine_wait_complete(reg_bitblt_t* bltreg)
+{
+	return e1356_wait_bitclr(&bltreg->ctrl0, 0x80, 5000);
+}
+static inline int
+e1356_engine_wait_busy(reg_bitblt_t* bltreg)
+{
+	return e1356_wait_bitset(&bltreg->ctrl0, 0x80, 5000);
+}
+
+static void
+e1356fb_engine_init(const struct e1356fb_par* par,
+		    struct fb_info_e1356* info)
+{
+	reg_bitblt_t* bltreg = info->reg.bitblt;
+    
+	e1356_engine_wait_complete(bltreg);
+
+	writeb(0, &bltreg->ctrl0);
+	writeb(0, &bltreg->ctrl1);
+	writeb(0, &bltreg->rop_code);
+	writeb(0, &bltreg->operation);
+	writeb(0, &bltreg->src_start_addr0);
+	writeb(0, &bltreg->src_start_addr1);
+	writeb(0, &bltreg->src_start_addr2);
+	writeb(0, &bltreg->dest_start_addr0);
+	writeb(0, &bltreg->dest_start_addr1);
+	writeb(0, &bltreg->dest_start_addr2);
+	writew(0, &bltreg->mem_addr_offset0);
+	writew(0, &bltreg->width0);
+	writew(0, &bltreg->height0);
+	writew(0, &bltreg->bg_color0);
+	writew(0, &bltreg->fg_color0);
+}
+
+
+static void doBlt_Write(const struct e1356fb_par* par,
+			struct fb_info_e1356* info,
+			blt_info_t* blt)
+{
+	reg_bitblt_t* bltreg = info->reg.bitblt;
+	int nWords, nTotalWords;
+	u32 srcphase, dstAddr;
+	u16* w16;
+	u32 stride = par->width_virt * par->Bpp;
+
+	dstAddr = blt->dst_x * par->Bpp + blt->dst_y * stride;
+	srcphase = (u32)blt->src & 1;
+    
+	if (blt->attribute & BLT_ATTR_TRANSPARENT)
+		writew(blt->bg_color, &bltreg->bg_color0);
+	else
+		writeb(blt->rop, &bltreg->rop_code);
+    
+	writeb(blt->operation, &bltreg->operation);
+	writeb((u8)srcphase, &bltreg->src_start_addr0);
+	writew(stride/2, &bltreg->mem_addr_offset0);
+
+	writeb(dstAddr, &bltreg->dest_start_addr0);
+	writeb(dstAddr>>8, &bltreg->dest_start_addr1);
+	writeb(dstAddr>>16, &bltreg->dest_start_addr2);
+
+	writew(blt->dst_width-1, &bltreg->width0);
+	writew(blt->dst_height-1, &bltreg->height0);
+
+	// program color format operation
+	writeb(par->bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
+
+	// start it up
+	writeb(0x80, &bltreg->ctrl0);
+
+	// wait for it to actually start
+	e1356_engine_wait_busy(bltreg);
+
+	// calculate the number of 16 bit words per one blt line
+
+	nWords = srcphase + ((blt->dst_width - srcphase)*par->Bpp + 1) / 2;
+	nTotalWords = nWords*blt->dst_height;
+	w16 = (u16*)((u32)blt->src & 0xfffffffe);   // Word aligned
+
+	while (nTotalWords > 0) {
+		int j, nFIFO;
+		u8 ctrl0;
+
+		// read the FIFO status
+		ctrl0 = readb(&bltreg->ctrl0);
+
+		if ((ctrl0 & 0x30) == 0x20)
+			// FIFO is at least half full, but not full
+			nFIFO = 1;
+		else if ((ctrl0 & 0x40) == 0)
+			// FIFO is empty
+			nFIFO = 16;
+		else
+			// FIFO is full
+			continue;
+
+		for (j = 0; j < nFIFO && nTotalWords > 0; j++,nTotalWords--)
+			writew(*w16++, info->reg.bitblt_data);
+	}
+
+	e1356_engine_wait_complete(bltreg);
+}
+
+
+static void
+doBlt_SolidFill(const struct e1356fb_par* par,
+		struct fb_info_e1356* info,
+		blt_info_t* blt)
+{
+	reg_bitblt_t* bltreg = info->reg.bitblt;
+	u32 width = blt->dst_width, height = blt->dst_height;
+	u32 stride = par->width_virt * par->Bpp;
+	u32 dest_addr = (blt->dst_y * stride) + (blt->dst_x * par->Bpp);
+
+	if (width == 0 || height == 0)
+		return;
+
+	// program dest address
+	writeb(dest_addr & 0x00ff, &bltreg->dest_start_addr0);
+	writeb((dest_addr>>8) & 0x00ff, &bltreg->dest_start_addr1);
+	writeb((dest_addr>>16) & 0x00ff, &bltreg->dest_start_addr2);
+
+	// program width and height of solid-fill blit
+	writew(width-1, &bltreg->width0);
+	writew(height-1, &bltreg->height0);
+
+	// program color of fill
+	writew(blt->fg_color, &bltreg->fg_color0);
+	// select solid-fill BLIT
+	writeb(BLT_SOLID_FILL, &bltreg->operation);
+	// program color format operation
+	writeb(par->bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
+	// program BLIT memory offset
+	writew(stride/2, &bltreg->mem_addr_offset0);
+
+	// start it up (self completes)
+	writeb(0x80, &bltreg->ctrl0);
+
+	e1356_engine_wait_complete(bltreg);
+}
+
+
+static void
+doBlt_Move(const struct e1356fb_par* par,
+	   struct fb_info_e1356* info,
+	   blt_info_t* blt)
+{
+	reg_bitblt_t* bltreg = info->reg.bitblt;
+	int neg_dir=0;
+	u32 dest_addr, src_addr;
+	u32 bpp = par->bpp;
+	u32 stride = par->width_virt * par->Bpp; // virt line length in bytes
+	u32 srcx = blt->src_x, srcy = blt->src_y;
+	u32 dstx = blt->dst_x, dsty = blt->dst_y;
+	u32 width = blt->dst_width, height = blt->dst_height;
+    
+	if (width == 0 || height == 0)
+		return;
+   
+	src_addr = srcx*par->Bpp + srcy*stride;
+	dest_addr = dstx*par->Bpp + dsty*stride;
+
+	/*
+	 * See if regions overlap and dest region is beyond source region.
+	 * If so, we need to do a move BLT in negative direction. Only applies
+	 * if the BLT is not transparent.
+	 */
+	if (!(blt->attribute & BLT_ATTR_TRANSPARENT)) {
+		if ((srcx + width  > dstx) && (srcx < dstx + width) &&
+		    (srcy + height > dsty) && (srcy < dsty + height) &&
+		    (dest_addr > src_addr)) {
+			neg_dir = 1;
+			// negative direction : get the coords of lower right corner
+			src_addr += stride * (height-1) + par->Bpp * (width-1);
+			dest_addr += stride * (height-1) + par->Bpp * (width-1);
+		}
+	}
+    
+	// program BLIT memory offset
+	writew(stride/2, &bltreg->mem_addr_offset0);
+
+	// program src and dest addresses
+	writeb(src_addr & 0x00ff, &bltreg->src_start_addr0);
+	writeb((src_addr>>8) & 0x00ff, &bltreg->src_start_addr1);
+	writeb((src_addr>>16) & 0x00ff, &bltreg->src_start_addr2);
+	writeb(dest_addr & 0x00ff, &bltreg->dest_start_addr0);
+	writeb((dest_addr>>8) & 0x00ff, &bltreg->dest_start_addr1);
+	writeb((dest_addr>>16) & 0x00ff, &bltreg->dest_start_addr2);
+
+	// program width and height of blit
+	writew(width-1, &bltreg->width0);
+	writew(height-1, &bltreg->height0);
+
+	// program color format operation
+	writeb(bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
+
+	// set the blt type
+	if (blt->attribute & BLT_ATTR_TRANSPARENT) {
+		writew(blt->bg_color, &bltreg->bg_color0);
+		writeb(BLT_MOVE_POS_TRANSP, &bltreg->operation); 
+	} else {
+		writeb(blt->rop, &bltreg->rop_code);
+		// select pos/neg move BLIT
+		writeb(neg_dir ? BLT_MOVE_NEG_ROP : BLT_MOVE_POS_ROP,
+		       &bltreg->operation); 
+	}
+
+	// start it up (self completes)
+	writeb(0x80, &bltreg->ctrl0);
+
+	e1356_engine_wait_complete(bltreg);
+}
+
+
+static void doBlt_ColorExpand(const struct e1356fb_par* par,
+			      struct fb_info_e1356* info,
+			      blt_info_t* blt)
+{
+	reg_bitblt_t* bltreg = info->reg.bitblt;
+	int i, j, nWords, Sx, Sy;
+	u32 dstAddr;
+	u16* wpt, *wpt1;
+	u32 stride = par->width_virt * par->Bpp;
+
+	if (blt->dst_width == 0 || blt->dst_height == 0)
+		return;
+
+	Sx = blt->src_x;
+	Sy = blt->src_y;
+
+	writeb((7 - Sx%8), &bltreg->rop_code);
+
+	writeb(blt->operation, &bltreg->operation);
+
+	writeb((u8)(Sx & 1), &bltreg->src_start_addr0);
+
+	dstAddr = blt->dst_x*par->Bpp + blt->dst_y * stride;
+	writeb(dstAddr, &bltreg->dest_start_addr0);
+	writeb(dstAddr>>8, &bltreg->dest_start_addr1);
+	writeb(dstAddr>>16, &bltreg->dest_start_addr2);
+
+	// program color format operation
+	writeb(par->bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
+	writew(stride/2, &bltreg->mem_addr_offset0);
+	writew(blt->dst_width-1, &bltreg->width0);
+	writew(blt->dst_height-1, &bltreg->height0);
+	writew(blt->bg_color, &bltreg->bg_color0);
+	writew(blt->fg_color, &bltreg->fg_color0);
+
+	// start it up
+	writeb(0x80, &bltreg->ctrl0);
+
+	// wait for it to actually start
+	e1356_engine_wait_busy(bltreg);
+
+	// calculate the number of 16 bit words per one blt line
+
+	nWords = (Sx%16 + blt->dst_width + 15)/16;
+
+	wpt = blt->src + (Sy*blt->srcstride + Sx/16)/2;
+
+	for (i = 0; i < blt->dst_height; i++) {
+		wpt1 = wpt;
+
+		for (j = 0; j < nWords; j++) {
+			// loop until FIFO becomes empty...
+			e1356_wait_bitclr(&bltreg->ctrl0, 0x40, 10000);
+			writew(*wpt1++, info->reg.bitblt_data);
+		}
+	
+		wpt += blt->srcstride/2;
+	}
+
+	e1356_engine_wait_complete(bltreg);
+}
+
+
+/*
+ * The BitBLT operation dispatcher
+ */
+static int
+doBlt(const struct e1356fb_par* par,
+      struct fb_info_e1356* info,
+      blt_info_t* blt)
+{
+	/*
+	 * Make sure we're not reentering in the middle of an
+	 * active BitBLT operation. ALWAYS call this dispatcher
+	 * and not one of the above BLT routines directly, or you
+	 * run the risk of overlapping BLT operations, which can
+	 * cause complete system hangs.
+     */
+	if (readb(&info->reg.bitblt->ctrl0) & 0x80)
+		return -ENXIO;
+    
+	switch (blt->operation) {
+	case BLT_MOVE_POS_ROP:
+	case BLT_MOVE_NEG_ROP:
+	case BLT_MOVE_POS_TRANSP:
+		doBlt_Move(par, info, blt);
+		break;
+	case BLT_COLOR_EXP:
+	case BLT_COLOR_EXP_TRANSP:
+		doBlt_ColorExpand(par, info, blt);
+		break;
+	case BLT_SOLID_FILL:
+		doBlt_SolidFill(par, info, blt);
+		break;
+	case BLT_WRITE_ROP:
+	case BLT_WRITE_TRANSP:
+		doBlt_Write(par, info, blt);
+		break;
+	case BLT_READ:
+	case BLT_PAT_FILL_ROP:
+	case BLT_PAT_FILL_TRANSP:
+	case BLT_MOVE_COLOR_EXP:
+	case BLT_MOVE_COLOR_EXP_TRANSP:
+		DPRINTK("BitBLT operation 0x%02x not implemented yet\n",
+			blt->operation);
+		return -ENXIO;
+	default:
+		DPRINTK("Unknown BitBLT operation 0x%02x\n", blt->operation);
+		return -ENXIO;
+	}
+    
+	return 0;
+}
+
+
+// Initializes blt->src and blt->srcstride
+static void fill_putcs_buffer(struct display *p,
+			      blt_info_t* blt,
+			      const unsigned short* str,
+			      int count)
+{   
+	int row, i, j;
+	u8* b1, *b2;
+	u32 fw = fontwidth(p);
+	u32 fwb = (fw + 7) >> 3;
+	u32 fh = fontheight(p);
+	int bytesPerChar = fwb * fh;
+
+	if (count*bytesPerChar > PAGE_SIZE) {
+		// Truncate the string if it overflows putcs_buffer, which is
+		// one page in size.
+		count = PAGE_SIZE/bytesPerChar - 1;
+	}
+
+	blt->srcstride = (fwb*count + 1) & ~1; //round up to be even
+	
+	b1 = (u8*)blt->src;
+
+	for (row = 0; row < fh; row++) {
+		b2 = b1;
+		for (i = 0; i < count; i++) {
+			for (j=0; j<fwb; j++)
+				*b2++ = p->fontdata[(str[i] & p->charmask) *
+						   bytesPerChar +
+						   row*fwb + j];
+		}
+		b1 += blt->srcstride;
+	}
+}
+
+
+/*
+ * Set the color of a palette entry in 8bpp mode 
+ */
+static inline void
+do_setpalentry(reg_lut_t* lut, unsigned regno,
+	       u8 r, u8 g, u8 b)
+{
+	writeb(0x00, &lut->mode);
+	writeb((u8)regno, &lut->addr);
+	writeb(r&0xf0, &lut->data);
+	writeb(g&0xf0, &lut->data);
+	writeb(b&0xf0, &lut->data);
+}
+
+   
+static void
+do_pan_var(struct fb_var_screeninfo* var, struct fb_info_e1356* info)
+{
+	u32 pixel_start, start_addr;
+	u8 pixel_pan;
+	struct e1356fb_par* par = &info->current_par;
+	reg_misc_t* misc = info->reg.misc;
+	reg_dispmode_t* dispmode = (IS_PANEL(info->fix.disp_type)) ?
+		info->reg.lcd_mode : info->reg.crttv_mode;
+	
+	pixel_start = var->yoffset * par->width_virt + var->xoffset;
+	start_addr = (pixel_start * par->Bpp) / 2;
+	pixel_pan = (par->bpp == 8) ? (u8)(pixel_start & 1) : 0;
+    
+	if (readb(&misc->disp_mode) != 0) {
+		reg_dispcfg_t* dispcfg = (IS_PANEL(info->fix.disp_type)) ?
+			info->reg.lcd_cfg : info->reg.crttv_cfg;
+
+		// wait for the end of the current VNDP
+		e1356_wait_bitclr(&dispcfg->vndp, 0x80, 5000);
+		// now wait for the start of a new VNDP
+		e1356_wait_bitset(&dispcfg->vndp, 0x80, 5000);
+	}
+    
+	writeb((u8)(start_addr & 0xff), &dispmode->start_addr0);
+	writeb((u8)((start_addr>>8) & 0xff), &dispmode->start_addr1);
+	writeb((u8)((start_addr>>16) & 0xff), &dispmode->start_addr2);
+	writeb(pixel_pan, &dispmode->pixel_panning);
+}
+
+
+/*
+ * Invert the hardware cursor image (timerfunc)  
+ */
+static void
+do_flashcursor(unsigned long ptr)
+{
+	u8 curs_ctrl;
+	struct fb_info_e1356* info = (struct fb_info_e1356 *)ptr;
+	reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ?
+		info->reg.lcd_inkcurs : info->reg.crttv_inkcurs;
+
+	spin_lock(&info->cursor.lock);
+	// toggle cursor enable bit
+	curs_ctrl = readb(&inkcurs->ctrl);
+	writeb((curs_ctrl ^ 0x01) & 0x01, &inkcurs->ctrl);
+	info->cursor.timer.expires = jiffies+HZ/2;
+	add_timer(&info->cursor.timer);
+	spin_unlock(&info->cursor.lock);
+}
+
+#ifdef SHADOW_FRAME_BUFFER
+/*
+ * Write BLT the shadow frame buffer to the real fb (timerfunc)  
+ */
+static void
+do_write_shadow_fb(unsigned long ptr)
+{
+	blt_info_t blt;
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)ptr;
+	struct fb_info* fb = &info->fb_info;
+	struct e1356fb_par* par = &info->current_par;
+	u32 stride = par->width_virt * par->Bpp;
+
+	unsigned long j_start = jiffies;
+    
+	blt.src_x = blt.src_y = 0;
+	blt.attribute = 0;
+	blt.dst_width = par->width;
+	blt.dst_height = par->height;
+	blt.dst_y = fb->var.yoffset;
+	blt.dst_x = fb->var.xoffset;
+	blt.operation = BLT_WRITE_ROP;
+	blt.rop = 0x0c; // ROP: destination = source
+	blt.src = (u16*)(info->shadow.fb + blt.dst_x * par->Bpp +
+			 blt.dst_y * stride);
+
+	doBlt(par, info, &blt);
+    
+	info->shadow.timer.expires = jiffies+HZ/2;
+	add_timer(&info->shadow.timer);
+
+	//DPRINTK("delta jiffies = %ld\n", jiffies - j_start);
+}
+#endif
+
+
+/* ------------------------------------------------------------------------- 
+ *              Hardware independent part, interface to the world
+ * ------------------------------------------------------------------------- */
+
+static void
+e1356_cfbX_clear_margins(struct vc_data* conp, struct display* p,
+			 int bottom_only)
+{
+	blt_info_t blt;
+	unsigned int cw=fontwidth(p);
+	unsigned int ch=fontheight(p);
+	unsigned int rw=p->var.xres % cw;
+	unsigned int bh=p->var.yres % ch;
+	unsigned int rs=p->var.xres - rw;
+	unsigned int bs=p->var.yres - bh;
+
+	//DPRINTK("\n");
+
+	if (!bottom_only && rw) { 
+		blt.dst_x = p->var.xoffset+rs;
+		blt.dst_y = p->var.yoffset;
+		blt.dst_height = p->var.yres;
+		blt.dst_width = rw;
+		blt.attribute = 0;
+		blt.fg_color = 0;
+		blt.operation = BLT_SOLID_FILL;
+		doBlt (&fb_info.current_par, &fb_info, &blt);
+	}
+    
+	if (bh) { 
+		blt.dst_x = p->var.xoffset;
+		blt.dst_y = p->var.yoffset+bs;
+		blt.dst_height = bh;
+		blt.dst_width = rs;
+		blt.attribute = 0;
+		blt.fg_color = 0;
+		blt.operation = BLT_SOLID_FILL;
+		doBlt (&fb_info.current_par, &fb_info, &blt);
+	}
+}
+
+static void
+e1356_cfbX_bmove(struct display* p, 
+		 int sy, 
+		 int sx, 
+		 int dy,
+		 int dx, 
+		 int height, 
+		 int width)
+{
+	blt_info_t blt;
+    
+	//DPRINTK("(%d,%d) to (%d,%d) size (%d,%d)\n", sx,sy,dx,dy,width,height);
+
+	blt.src_x = fontwidth_x8(p)*sx;
+	blt.src_y = fontheight(p)*sy;
+	blt.dst_x = fontwidth_x8(p)*dx;
+	blt.dst_y = fontheight(p)*dy;
+	blt.src_height = blt.dst_height = fontheight(p)*height;
+	blt.src_width = blt.dst_width = fontwidth_x8(p)*width;
+	blt.attribute = 0;
+	blt.rop = 0x0c;
+	/*
+	 * The move BLT routine will actually decide between a pos/neg
+	 * move BLT. This is just so that the BLT dispatcher knows to
+	 * call the move BLT routine.
+	 */
+	blt.operation = BLT_MOVE_POS_ROP;
+
+	doBlt (&fb_info.current_par, &fb_info, &blt);
+}
+
+static void
+e1356_cfb8_putc(struct vc_data* conp,
+		struct display* p,
+		int c, int yy,int xx)
+{   
+	blt_info_t blt;
+	u32 fgx,bgx;
+	u32 fw = fontwidth_x8(p);
+	u32 fh = fontheight(p);
+	u16 cs = (u16)c;
+
+	fgx = attr_fgcol(p, c);
+	bgx = attr_bgcol(p, c);
+
+	blt.src_x = blt.src_y = 0;
+	blt.attribute = 0;
+	blt.dst_width = fw;
+	blt.dst_height = fh;
+	blt.dst_y = yy * fh;
+	blt.dst_x = xx * fw;
+	blt.bg_color = bgx;
+	blt.fg_color = fgx;
+	blt.operation = BLT_COLOR_EXP;
+	blt.src = fb_info.putcs_buffer;
+	fill_putcs_buffer(p, &blt, &cs, 1);
+
+	doBlt(&fb_info.current_par, &fb_info, &blt);
+
+}
+
+static void
+e1356_cfb16_putc(struct vc_data* conp,
+		 struct display* p,
+		 int c, int yy,int xx)
+{   
+	blt_info_t blt;
+	u32 fgx,bgx;
+	u32 fw = fontwidth_x8(p);
+	u32 fh = fontheight(p);
+	u16 cs = (u16)c;
+    
+	fgx = ((u16*)p->dispsw_data)[attr_fgcol(p,c)];
+	bgx = ((u16*)p->dispsw_data)[attr_bgcol(p,c)];
+
+	blt.src_x = blt.src_y = 0;
+	blt.attribute = 0;
+	blt.dst_width = fw;
+	blt.dst_height = fh;
+	blt.dst_y = yy * fh;
+	blt.dst_x = xx * fw;
+	blt.bg_color = bgx;
+	blt.fg_color = fgx;
+	blt.operation = BLT_COLOR_EXP;
+	blt.src = fb_info.putcs_buffer;
+	fill_putcs_buffer(p, &blt, &cs, 1);
+
+	doBlt(&fb_info.current_par, &fb_info, &blt);
+}
+
+
+static void
+e1356_cfb8_putcs(struct vc_data* conp,
+		 struct display* p,
+		 const unsigned short *s,int count,int yy,int xx)
+{
+	blt_info_t blt;
+	u32 fgx,bgx;
+	u32 fw = fontwidth_x8(p);
+	u32 fh = fontheight(p);
+
+	//DPRINTK("\n");
+
+	fgx=attr_fgcol(p, *s);
+	bgx=attr_bgcol(p, *s);
+
+	blt.src_x = blt.src_y = 0;
+	blt.attribute = 0;
+	blt.dst_width = count * fw;
+	blt.dst_height = fh;
+	blt.dst_y = yy * fh;
+	blt.dst_x = xx * fw;
+	blt.bg_color = bgx;
+	blt.fg_color = fgx;
+	blt.operation = BLT_COLOR_EXP;
+	blt.src = fb_info.putcs_buffer;
+	fill_putcs_buffer(p, &blt, s, count);
+
+	doBlt(&fb_info.current_par, &fb_info, &blt);
+}
+
+static void
+e1356_cfb16_putcs(struct vc_data* conp,
+		  struct display* p,
+		  const unsigned short *s,int count,int yy,int xx)
+{
+	blt_info_t blt;
+	u32 fgx,bgx;
+	u32 fw = fontwidth_x8(p);
+	u32 fh = fontheight(p);
+
+	//DPRINTK("\n");
+
+	fgx=((u16*)p->dispsw_data)[attr_fgcol(p,*s)];
+	bgx=((u16*)p->dispsw_data)[attr_bgcol(p,*s)];
+
+	blt.src_x = blt.src_y = 0;
+	blt.attribute = 0;
+	blt.dst_width = count * fw;
+	blt.dst_height = fh;
+	blt.dst_y = yy * fh;
+	blt.dst_x = xx * fw;
+	blt.bg_color = bgx;
+	blt.fg_color = fgx;
+	blt.operation = BLT_COLOR_EXP;
+	blt.src = fb_info.putcs_buffer;
+	fill_putcs_buffer(p, &blt, s, count);
+
+	doBlt(&fb_info.current_par, &fb_info, &blt);
+}
+
+
+static void
+e1356_cfb8_clear(struct vc_data* conp, 
+		 struct display* p, 
+		 int sy,
+		 int sx, 
+		 int height, 
+		 int width)
+{
+	blt_info_t blt;
+	u32 bg = attr_bgcol_ec(p,conp);
+
+	//DPRINTK("(%d,%d) size (%d,%d)\n", sx,sy,width,height);
+
+	blt.dst_x = fontwidth_x8(p)*sx;
+	blt.dst_y = fontheight(p)*sy;
+	blt.dst_height = fontheight(p)*height;
+	blt.dst_width = fontwidth_x8(p)*width;
+	blt.attribute = 0;
+	blt.fg_color = bg;
+	blt.operation = BLT_SOLID_FILL;
+
+	doBlt (&fb_info.current_par, &fb_info, &blt);
+}
+
+static void
+e1356_cfb16_clear(struct vc_data* conp, 
+		  struct display* p, 
+		  int sy,
+		  int sx, 
+		  int height, 
+		  int width)
+{
+	blt_info_t blt;
+	u32 bg = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
+
+	//DPRINTK("(%d,%d) size (%d,%d)\n", sx,sy,width,height);
+
+	blt.dst_x = fontwidth_x8(p)*sx;
+	blt.dst_y = fontheight(p)*sy;
+	blt.dst_height = fontheight(p)*height;
+	blt.dst_width = fontwidth_x8(p)*width;
+	blt.attribute = 0;
+	blt.fg_color = bg;
+	blt.operation = BLT_SOLID_FILL;
+
+	doBlt (&fb_info.current_par, &fb_info, &blt);
+}
+
+
+static void
+e1356_cfbX_revc(struct display *p, int xx, int yy)
+{
+	// not used if h/w cursor
+	//DPRINTK("\n");
+}
+
+static void
+e1356_cfbX_cursor(struct display *p, int mode, int x, int y) 
+{
+	unsigned long flags;
+	struct fb_info_e1356 *info=(struct fb_info_e1356 *)p->fb_info;
+	reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ?
+		info->reg.lcd_inkcurs : info->reg.crttv_inkcurs;
+    
+	//DPRINTK("\n");
+
+	if (mode == CM_ERASE) {
+		if (info->cursor.state != CM_ERASE) {
+			spin_lock_irqsave(&info->cursor.lock,flags);
+			info->cursor.state = CM_ERASE;
+			del_timer(&(info->cursor.timer));
+			writeb(0x00, &inkcurs->ctrl);
+			spin_unlock_irqrestore(&info->cursor.lock,flags);
+		}
+		return;
+	}
+    
+	if ((p->conp->vc_cursor_type & CUR_HWMASK) != info->cursor.type)
+		e1356fb_createcursor(p);
+    
+	x *= fontwidth_x8(p);
+	y *= fontheight(p);
+	x -= p->var.xoffset;
+	y -= p->var.yoffset;
+    
+	spin_lock_irqsave(&info->cursor.lock,flags);
+	if ((x != info->cursor.x) || (y != info->cursor.y) ||
+	    (info->cursor.redraw)) {
+		info->cursor.x = x;
+		info->cursor.y = y;
+		info->cursor.redraw = 0;
+		writeb(0x01, &inkcurs->ctrl);
+		writew(x, &inkcurs->x_pos0);
+		writew(y, &inkcurs->y_pos0);
+		/* fix cursor color - XFree86 forgets to restore it properly */
+		writeb(0x00, &inkcurs->blue0);
+		writeb(0x00, &inkcurs->green0);
+		writeb(0x00, &inkcurs->red0);
+		writeb(0x1f, &inkcurs->blue1);
+		writeb(0x3f, &inkcurs->green1);
+		writeb(0x1f, &inkcurs->red1);
+	}
+
+	info->cursor.state = CM_DRAW;
+	mod_timer(&info->cursor.timer, jiffies+HZ/2);
+	spin_unlock_irqrestore(&info->cursor.lock,flags);
+}
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch fbcon_e1356_8 = {
+	setup:		fbcon_cfb8_setup, 
+	bmove:		e1356_cfbX_bmove, 
+	clear:		e1356_cfb8_clear, 
+	putc:		e1356_cfb8_putc,
+	putcs:		e1356_cfb8_putcs, 
+	revc:		e1356_cfbX_revc,   
+	cursor:		e1356_cfbX_cursor, 
+	clear_margins:	e1356_cfbX_clear_margins,
+	fontwidthmask:	FONTWIDTHRANGE(6,16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_e1356_16 = {
+	setup:		fbcon_cfb16_setup, 
+	bmove:		e1356_cfbX_bmove, 
+	clear:		e1356_cfb16_clear, 
+	putc:		e1356_cfb16_putc,
+	putcs:		e1356_cfb16_putcs, 
+	revc:		e1356_cfbX_revc, 
+	cursor:		e1356_cfbX_cursor, 
+	clear_margins:	e1356_cfbX_clear_margins,
+	fontwidthmask:	FONTWIDTHRANGE(6,16)
+};
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static void
+e1356fb_set_par(const struct e1356fb_par* par,
+		struct fb_info_e1356* info)
+{
+	reg_dispcfg_t* dispcfg=NULL;
+	reg_dispmode_t* dispmode=NULL;
+	u8* pclk_cfg=NULL;
+	u8 width, hndp=0, hsync_start=0, hsync_width=0;
+	u8 vndp, vsync_start, vsync_width=0, display_mode;
+	u8 main_display_mode=0;
+	u16 height, addr_offset;
+	int disp_type = info->fix.disp_type;
+
+	DPRINTK("%dx%d-%dbpp @ %d Hz, %d kHz hsync\n",
+		par->width, par->height, par->bpp,
+		par->vsync_freq, (((2*par->hsync_freq)/1000)+1)/2);
+#ifdef E1356FB_VERBOSE_DEBUG
+	dump_par(par);
+#endif
+    
+	info->current_par = *par;
+
+	width = (par->width >> 3) - 1;
+	display_mode = (par->bpp == 8) ? 0x03 : 0x05;
+	addr_offset = (par->width_virt * par->Bpp) / 2;
+	vsync_start = (disp_type == DISP_TYPE_LCD) ? 0 : par->vsync_start - 1;
+	height = par->height - 1;
+	vndp = par->vert_ndp - 1;
+
+	switch (disp_type) {
+	case DISP_TYPE_LCD:
+		dispcfg = info->reg.lcd_cfg;
+		dispmode = info->reg.lcd_mode;
+		pclk_cfg = &info->reg.clk_cfg->lcd_pclk_cfg;
+		hndp = (par->horiz_ndp >> 3) - 1;
+		hsync_start = 0;
+		hsync_width = par->hsync_pol ? 0x00 : 0x80;
+		vsync_width = par->vsync_pol ? 0x00 : 0x80;
+		main_display_mode = 0x01;
+		break;
+	case DISP_TYPE_TFT:
+		dispcfg = info->reg.lcd_cfg;
+		dispmode = info->reg.lcd_mode;
+		pclk_cfg = &info->reg.clk_cfg->lcd_pclk_cfg;
+		hndp = (par->horiz_ndp >> 3) - 1;
+		hsync_start = (par->bpp == 8) ?
+			(par->hsync_start - 4) >> 3 :
+				(par->hsync_start - 6) >> 3;
+		hsync_width =
+			(par->hsync_pol ? 0x80 : 0x00) |
+			((par->hsync_width >> 3) - 1);
+		vsync_width =
+			(par->vsync_pol ? 0x80 : 0x00) |
+			(par->vsync_width - 1);
+		main_display_mode = 0x01;
+		break;
+	case DISP_TYPE_CRT:
+		dispcfg = info->reg.crttv_cfg;
+		dispmode = info->reg.crttv_mode;
+		pclk_cfg = &info->reg.clk_cfg->crttv_pclk_cfg;
+		hndp = (par->horiz_ndp >> 3) - 1;
+		hsync_start = (par->bpp == 8) ?
+			(par->hsync_start - 3) >> 3 :
+				(par->hsync_start - 5) >> 3;
+		hsync_width =
+			(par->hsync_pol ? 0x80 : 0x00) |
+			((par->hsync_width >> 3) - 1);
+		vsync_width =
+			(par->vsync_pol ? 0x80 : 0x00) |
+			(par->vsync_width - 1);
+		main_display_mode = 0x02;
+		break;
+	case DISP_TYPE_NTSC:
+	case DISP_TYPE_PAL:
+		dispcfg = info->reg.crttv_cfg;
+		dispmode = info->reg.crttv_mode;
+		pclk_cfg = &info->reg.clk_cfg->crttv_pclk_cfg;
+		hndp = (disp_type == DISP_TYPE_PAL) ?
+			(par->horiz_ndp - 7) >> 3 :
+				(par->horiz_ndp - 6) >> 3;
+		hsync_start = (par->bpp == 8) ?
+			(par->hsync_start + 7) >> 3 :
+				(par->hsync_start + 5) >> 3;
+		hsync_width = 0;
+		vsync_width = 0;
+		main_display_mode = (info->fix.tv_filt & TV_FILT_FLICKER) ?
+			0x06 : 0x04;
+		break;
+	}
+
+	// Blast the regs!
+	// note: reset panning/scrolling (set start-addr and
+	// pixel pan regs to 0). Panning is handled by pan_display.
+
+	e1356_engine_wait_complete(info->reg.bitblt);
+
+	// disable display while initializing
+	writeb(0, &info->reg.misc->disp_mode);
+
+	writeb(par->ipclk.pixclk_bits, pclk_cfg);
+
+	writeb(width, &dispcfg->hdw);
+	writeb(hndp, &dispcfg->hndp);
+	writeb(hsync_start, &dispcfg->hsync_start);
+	writeb(hsync_width, &dispcfg->hsync_pulse);
+	writew(height, &dispcfg->vdh0);
+	writeb(vndp, &dispcfg->vndp);
+	writeb(vsync_start, &dispcfg->vsync_start);
+	writeb(vsync_width, &dispcfg->vsync_pulse);
+
+	writeb(display_mode, &dispmode->disp_mode);
+	if (info->fix.mmunalign && info->mmaped)
+		writeb(1, &dispmode->start_addr0);
+	else
+		writeb(0, &dispmode->start_addr0);
+	writeb(0, &dispmode->start_addr1);
+	writeb(0, &dispmode->start_addr2);
+	writew(addr_offset, &dispmode->mem_addr_offset0);
+	writeb(0, &dispmode->pixel_panning);
+
+	// reset BitBlt engine
+	e1356fb_engine_init(par, info);
+
+#ifdef E1356FB_VERBOSE_DEBUG
+	dump_display_regs(dispcfg, dispmode);
+#endif
+
+	/* clear out framebuffer memory */
+	fbfill(fb_info.membase_virt, 0, fb_info.fb_size);
+	// finally, enable display!
+	writeb(main_display_mode, &info->reg.misc->disp_mode); 
+}
+
+
+static int
+e1356fb_verify_timing(struct e1356fb_par* par,
+		      const struct fb_info_e1356* info)
+{
+	int disp_type = info->fix.disp_type;
+
+	// timing boundary checks
+	if (par->horiz_ndp > max_hndp[disp_type]) {
+		DPRINTK("horiz_ndp too big: %d\n", par->horiz_ndp);
+		return -EINVAL;
+	}
+	if (par->vert_ndp > max_vndp[disp_type]) {
+		DPRINTK("vert_ndp too big: %d\n", par->vert_ndp);
+		return -EINVAL;
+	}
+
+	if (disp_type != DISP_TYPE_LCD) {
+		if (par->hsync_start >
+		    max_hsync_start[(par->bpp==16)][disp_type]) {
+			DPRINTK("hsync_start too big: %d\n",
+				par->hsync_start);
+			return -EINVAL;
+		}
+		if (par->vsync_start > max_vsync_start[disp_type]) {
+			DPRINTK("vsync_start too big: %d\n",
+				par->vsync_start);
+			return -EINVAL;
+		}
+		if (!IS_TV(disp_type)) {
+			if (par->hsync_width > max_hsync_width[disp_type]) {
+				DPRINTK("hsync_width too big: %d\n",
+					par->hsync_width);
+				return -EINVAL;
+			}
+			if (par->vsync_width > max_vsync_width[disp_type]) {
+				DPRINTK("vsync_width too big: %d\n",
+					par->vsync_width);
+				return -EINVAL;
+			}
+		}
+	}
+
+	if (IS_TV(disp_type)) {
+		int tv_pixclk = (disp_type == DISP_TYPE_NTSC) ?
+			NTSC_PIXCLOCK : PAL_PIXCLOCK;
+		if (info->fix.tv_filt & TV_FILT_FLICKER)
+			tv_pixclk *= 2;
+		
+		if (par->ipclk.pixclk_d != tv_pixclk) {
+			DPRINTK("invalid TV pixel clock %u kHz\n",
+				par->ipclk.pixclk_d);
+			return -EINVAL;
+		}
+	}
+	
+	if (e1356_calc_pixclock(info, &par->ipclk) < 0) {
+		DPRINTK("can't set pixel clock %u kHz\n",
+			par->ipclk.pixclk_d);
+		return -EINVAL;
+	}
+ 
+#ifdef E1356FB_VERBOSE_DEBUG
+	DPRINTK("desired pixclock = %d kHz, actual = %d kHz, error = %d%%\n",
+		par->ipclk.pixclk_d, par->ipclk.pixclk, par->ipclk.error);
+#endif
+    
+	if (disp_type != DISP_TYPE_LCD) {
+		if (par->horiz_ndp < par->hsync_start + par->hsync_width) {
+			DPRINTK("invalid horiz. timing\n");
+			return -EINVAL;
+		}
+		if (par->vert_ndp < par->vsync_start + par->vsync_width) {
+			DPRINTK("invalid vert. timing\n");
+			return -EINVAL;
+		}
+
+		// SED1356 Hardware Functional Spec, section 13.5
+		if (disp_type == DISP_TYPE_NTSC &&
+		    ((par->width + par->horiz_ndp != 910) ||
+		     (par->height + 2*par->vert_ndp+1 != 525))) {
+			DPRINTK("invalid NTSC timing\n");
+			return -EINVAL;
+		} else if (disp_type == DISP_TYPE_PAL &&
+			   ((par->width + par->horiz_ndp != 1135) ||
+			    (par->height + 2*par->vert_ndp+1 != 625))) {
+			DPRINTK("invalid PAL timing\n");
+			return -EINVAL;
+		}
+	}
+    
+	par->hsync_freq = (1000 * par->ipclk.pixclk) /
+		(par->width + par->horiz_ndp);
+	par->vsync_freq = par->hsync_freq / (par->height + par->vert_ndp);
+	
+	if (par->hsync_freq < 30000 || par->hsync_freq > 90000) {
+		DPRINTK("hsync freq too %s: %u Hz\n",
+			par->hsync_freq < 30000 ? "low" : "high",
+			par->hsync_freq);
+		return -EINVAL;
+	}
+	if (par->vsync_freq < 50 || par->vsync_freq > 110) {
+		DPRINTK("vsync freq too %s: %u Hz\n",
+			par->vsync_freq < 50 ? "low" : "high",
+			par->vsync_freq);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+e1356fb_verify_par(struct e1356fb_par* par,
+		   const struct fb_info_e1356* info)
+{
+	int disp_type = info->fix.disp_type;
+    
+	if (par->bpp != 8 && par->bpp != 16) {
+		DPRINTK("depth not supported: %u bpp\n", par->bpp);
+		return -EINVAL;
+	}
+
+	if (par->width > par->width_virt) {
+		DPRINTK("virtual x resolution < physical x resolution not possible\n");
+		return -EINVAL;
+	}
+
+	if (par->height > par->height_virt) {
+		DPRINTK("virtual y resolution < physical y resolution not possible\n");
+		return -EINVAL;
+	}
+
+	if (par->width < 320 || par->width > 1024) {
+		DPRINTK("width not supported: %u\n", par->width);
+		return -EINVAL;
+	}
+
+	if ((disp_type == DISP_TYPE_LCD && (par->width % 16)) ||
+	    (disp_type == DISP_TYPE_TFT && (par->width % 8))) {
+		DPRINTK("invalid width for panel type: %u\n", par->width);
+		return -EINVAL;
+	}
+
+	if (par->height < 200 || par->height > 1024) {
+		DPRINTK("height not supported: %u\n", par->height);
+		return -EINVAL;
+	}
+
+	if (par->width_virt * par->height_virt * par->Bpp >
+	    info->fb_size) {
+		DPRINTK("not enough memory for virtual screen (%ux%ux%u)\n",
+			par->width_virt, par->height_virt, par->bpp);
+		return -EINVAL;
+	}
+
+	return e1356fb_verify_timing(par, info);
+}
+
+
+static int
+e1356fb_var_to_par(const struct fb_var_screeninfo* var,
+		   struct e1356fb_par* par,
+		   const struct fb_info_e1356* info)
+{
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		DPRINTK("interlace not supported\n");
+		return -EINVAL;
+	}
+
+	memset(par, 0, sizeof(struct e1356fb_par));
+
+	par->width       = (var->xres + 15) & ~15; /* could sometimes be 8 */
+	par->width_virt  = var->xres_virtual;
+	par->height      = var->yres;
+	par->height_virt = var->yres_virtual;
+	par->bpp         = var->bits_per_pixel;
+	par->Bpp         = (par->bpp + 7) >> 3;
+
+	par->ipclk.pixclk_d = PICOS2KHZ(var->pixclock);
+
+	par->hsync_start = var->right_margin;
+	par->hsync_width = var->hsync_len;
+
+	par->vsync_start = var->lower_margin;
+	par->vsync_width = var->vsync_len;
+
+	par->horiz_ndp = var->left_margin + var->right_margin + var->hsync_len;
+	par->vert_ndp = var->upper_margin + var->lower_margin + var->vsync_len;
+
+	par->hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0;
+	par->vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0;
+
+	par->cmap_len  = (par->bpp == 8) ? 256 : 16;
+
+	return e1356fb_verify_par(par, info);
+}
+
+static int
+e1356fb_par_to_var(struct fb_var_screeninfo* var,
+		   struct e1356fb_par* par,
+		   const struct fb_info_e1356* info)
+{
+	struct fb_var_screeninfo v;
+	int ret;
+    
+	// First, make sure par is valid.
+	if ((ret = e1356fb_verify_par(par, info)))
+		return ret;
+
+	memset(&v, 0, sizeof(struct fb_var_screeninfo));
+	v.xres_virtual   = par->width_virt;
+	v.yres_virtual   = par->height_virt;
+	v.xres           = par->width;
+	v.yres           = par->height;
+	v.right_margin   = par->hsync_start;
+	v.hsync_len      = par->hsync_width;
+	v.left_margin    = par->horiz_ndp - par->hsync_start - par->hsync_width;
+	v.lower_margin   = par->vsync_start;
+	v.vsync_len      = par->vsync_width;
+	v.upper_margin   = par->vert_ndp - par->vsync_start - par->vsync_width;
+	v.bits_per_pixel = par->bpp;
+
+	switch(par->bpp) {
+	case 8:
+		v.red.offset = v.green.offset = v.blue.offset = 0;
+		v.red.length = v.green.length = v.blue.length = 4;
+		break;
+	case 16:
+		v.red.offset   = 11;
+		v.red.length   = 5;
+		v.green.offset = 5;
+		v.green.length = 6;
+		v.blue.offset  = 0;
+		v.blue.length  = 5;
+		break;
+	}
+
+	v.height = v.width = -1;
+	v.pixclock = KHZ2PICOS(par->ipclk.pixclk);
+
+	if (par->hsync_pol)
+		v.sync |= FB_SYNC_HOR_HIGH_ACT;
+	if (par->vsync_pol)
+		v.sync |= FB_SYNC_VERT_HIGH_ACT;
+
+	*var = v;
+	return 0;
+}
+
+static int
+e1356fb_encode_fix(struct fb_fix_screeninfo*  fix,
+		   const struct e1356fb_par*   par,
+		   const struct fb_info_e1356* info)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+    
+	strcpy(fix->id, "Epson SED1356");
+	fix->smem_start  = info->fix.membase_phys;
+	fix->smem_len    = info->fb_size;
+	fix->mmio_start  = info->fix.regbase_phys;
+	fix->mmio_len    = info->regbase_size;
+	fix->accel       = FB_ACCEL_EPSON_SED1356;
+	fix->type        = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux    = 0;
+	fix->line_length = par->width_virt * par->Bpp;
+	fix->visual      =
+		(par->bpp == 8) ? FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;
+    
+	fix->xpanstep    = info->fix.nopan ? 0 : 1;
+	fix->ypanstep    = info->fix.nopan ? 0 : 1;
+	fix->ywrapstep   = 0;
+    
+	return 0;
+}
+
+static int e1356fb_open(struct fb_info *fb, int user)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+        if (user) {
+                info->open++;
+	}
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int e1356fb_release(struct fb_info *fb, int user)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+        if (user && info->open) {
+                info->open--;
+		if (info->open == 0)
+                        info->mmaped = 0;
+	}
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int
+e1356fb_get_fix(struct fb_fix_screeninfo *fix, 
+		int con,
+		struct fb_info *fb)
+{
+	const struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	struct e1356fb_par par;
+
+	//DPRINTK("\n");
+
+	if (con == -1)
+		par = info->current_par;
+	else
+		e1356fb_var_to_par(&fb_display[con].var, &par, info);
+	e1356fb_encode_fix(fix, &par, info);
+	return 0;
+}
+
+static int
+e1356fb_get_var(struct fb_var_screeninfo *var, 
+		int con,
+		struct fb_info *fb)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+
+	//DPRINTK("\n");
+
+	if (con == -1)
+		e1356fb_par_to_var(var, &info->current_par, info);
+	else
+		*var = fb_display[con].var;
+	return 0;
+}
+ 
+static void
+e1356fb_set_dispsw(struct display *disp, 
+		   struct fb_info_e1356 *info,
+		   int bpp, 
+		   int accel)
+{
+	struct e1356fb_fix* fix = &info->fix;
+	//DPRINTK("\n");
+
+	if (disp->dispsw && disp->conp) 
+		fb_con.con_cursor(disp->conp, CM_ERASE);
+	switch (bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = fix->noaccel ? &fbcon_cfb8 : &fbcon_e1356_8;
+		if (fix->nohwcursor)
+			fbcon_e1356_8.cursor = NULL;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		disp->dispsw = fix->noaccel ? &fbcon_cfb16 : &fbcon_e1356_16;
+		disp->dispsw_data = info->fbcon_cmap16;
+		if (fix->nohwcursor)
+			fbcon_e1356_16.cursor = NULL;
+		break;
+#endif
+	default:
+		disp->dispsw = &fbcon_dummy;
+	}
+   
+}
+
+static int
+e1356fb_set_var(struct fb_var_screeninfo *var, 
+		int con,
+		struct fb_info *fb)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	struct e1356fb_par par;
+	struct display *display;
+	int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
+	int activate = var->activate;
+	int j,k;
+    
+	DPRINTK("\n");
+	
+	if (con >= 0)
+		display = &fb_display[con];
+	else
+		display = fb->disp;	/* used during initialization */
+   
+	if ((err = e1356fb_var_to_par(var, &par, info))) {
+		struct fb_videomode *dm;
+		/*
+		 * this mode didn't pass the tests. Try the
+		 * corresponding mode from our own modedb.
+		 */
+		DPRINTK("req mode failed, trying SED1356 %dx%d mode\n",
+			var->xres, var->yres);
+		if (e1356fb_get_mode(info, var->xres,
+				     var->yres, NULL, &dm) < 0) {
+			DPRINTK("no SED1356 %dx%d mode found, failed\n",
+				var->xres, var->yres);
+			return err;
+		}
+		fb_videomode_to_var(dm, var);
+		if ((err = e1356fb_var_to_par(var, &par, info))) {
+			DPRINTK("SED1356 %dx%d mode failed\n",
+				var->xres, var->yres);
+			return err;
+		}
+	}
+	
+	if (info->fix.tv_filt & TV_FILT_FLICKER)
+		printk("e1356fb: TV flicker filter enabled\n");
+    
+	e1356fb_par_to_var(var, &par, info);
+   
+	if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+		oldxres  = display->var.xres;
+		oldyres  = display->var.yres;
+		oldvxres = display->var.xres_virtual;
+		oldvyres = display->var.yres_virtual;
+		oldbpp   = display->var.bits_per_pixel;
+		oldaccel = display->var.accel_flags;
+		display->var = *var;
+		if (con < 0                         ||
+		    oldxres  != var->xres           || 
+		    oldyres  != var->yres           ||
+		    oldvxres != var->xres_virtual   || 
+		    oldvyres != var->yres_virtual   ||
+		    oldbpp   != var->bits_per_pixel || 
+		    oldaccel != var->accel_flags) {
+			struct fb_fix_screeninfo fix;
+	    
+			e1356fb_encode_fix(&fix, &par, info);
+			display->screen_base    = info->membase_virt;
+			display->visual         = fix.visual;
+			display->type           = fix.type;
+			display->type_aux       = fix.type_aux;
+			display->ypanstep       = fix.ypanstep;
+			display->ywrapstep      = fix.ywrapstep;
+			display->line_length    = fix.line_length;
+			display->next_line      = fix.line_length;
+			display->can_soft_blank = 1;
+			display->inverse        = 0;
+			accel = var->accel_flags & FB_ACCELF_TEXT;
+			e1356fb_set_dispsw(display, info, par.bpp, accel);
+	 
+			if (info->fix.nopan)
+				display->scrollmode = SCROLL_YREDRAW;
+	
+			if (info->fb_info.changevar)
+				(*info->fb_info.changevar)(con);
+		}
+		if (var->bits_per_pixel==8)
+			for(j = 0; j < 16; j++) {
+				k = color_table[j];
+				fb_info.palette[j].red   = default_red[k];
+				fb_info.palette[j].green = default_grn[k];
+				fb_info.palette[j].blue  = default_blu[k];
+			}
+      
+		del_timer(&(info->cursor.timer)); 
+		fb_info.cursor.state=CM_ERASE;
+	
+		if (!info->fb_info.display_fg ||
+		    info->fb_info.display_fg->vc_num == con || con < 0)
+			e1356fb_set_par(&par, info);
+
+		if (!info->fix.nohwcursor) 
+			if (display && display->conp)
+				e1356fb_createcursor( display );
+		info->cursor.redraw = 1;
+
+		if (oldbpp != var->bits_per_pixel || con < 0) {
+			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+				return err;
+			e1356fb_install_cmap(display, &(info->fb_info));
+		}
+	}
+  
+	return 0;
+}
+
+static int
+e1356fb_pan_display(struct fb_var_screeninfo* var, 
+		    int con,
+		    struct fb_info* fb)
+{
+	struct fb_info_e1356* info = (struct fb_info_e1356*)fb;
+	struct e1356fb_par* par = &info->current_par;
+    
+	//DPRINTK("\n");
+
+	if (info->fix.nopan)
+		return -EINVAL;
+
+	if ((int)var->xoffset < 0 ||
+	    var->xoffset + par->width > par->width_virt ||
+	    (int)var->yoffset < 0 ||
+	    var->yoffset + par->height > par->height_virt)
+		return -EINVAL;
+    
+	if (con == currcon)
+		do_pan_var(var, info);
+    
+	fb_display[con].var.xoffset = var->xoffset;
+	fb_display[con].var.yoffset = var->yoffset; 
+
+	return 0;
+}
+
+static int
+e1356fb_get_cmap(struct fb_cmap *cmap, 
+		 int kspc, 
+		 int con,
+		 struct fb_info *fb)
+{
+	struct fb_info_e1356* info = (struct fb_info_e1356*)fb;
+	struct display *d = (con<0) ? fb->disp : fb_display + con;
+   
+	//DPRINTK("\n");
+
+	if (con == currcon) {
+		/* current console? */
+		return fb_get_cmap(cmap, kspc, e1356fb_getcolreg, fb);
+	} else if (d->cmap.len) {
+		/* non default colormap? */
+		fb_copy_cmap(&d->cmap, cmap, kspc ? 0 : 2);
+	} else {
+		fb_copy_cmap(fb_default_cmap(info->current_par.cmap_len),
+			     cmap, kspc ? 0 : 2);
+	}
+	return 0;
+}
+
+static int
+e1356fb_set_cmap(struct fb_cmap *cmap, 
+		 int kspc, 
+		 int con,
+		 struct fb_info *fb)
+{
+	struct display *d = (con<0) ? fb->disp : fb_display + con;
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	int cmap_len = (info->current_par.bpp == 8) ? 256 : 16;
+
+	//DPRINTK("\n");
+
+	if (d->cmap.len!=cmap_len) {
+		int err;
+		if ((err = fb_alloc_cmap(&d->cmap, cmap_len, 0)))
+			return err;
+	}
+    
+	if (con == currcon) {
+		/* current console? */
+		return fb_set_cmap(cmap, kspc, e1356fb_setcolreg, fb);
+	} else {
+		fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
+	}
+	return 0;
+}
+
+static int
+e1356fb_ioctl(struct inode *inode, 
+	      struct file *file, 
+	      u_int cmd,
+	      u_long arg, 
+	      int con, 
+	      struct fb_info *fb)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	blt_info_t blt;
+	u16* src = NULL;
+	int ret=0;
+    
+	switch (cmd) {
+	case FBIO_SED1356_BITBLT:
+		if (copy_from_user(&blt, (void *)arg, sizeof(blt_info_t)))
+			return -EFAULT;
+		if (blt.src) {
+			if ((ret = verify_area(VERIFY_READ,
+					       (void*)blt.src, blt.srcsize)))
+				return ret;
+			if ((src = (u16*)kmalloc(blt.srcsize,
+						 GFP_KERNEL)) == NULL)
+				return -ENOMEM;
+			if (copy_from_user(src, (void *)blt.src, blt.srcsize))
+				return -EFAULT;
+			blt.src = src;
+		}
+		ret = doBlt(&info->current_par, info, &blt);
+		if (src)
+			kfree(src);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+
+static int
+e1356fb_mmap(struct fb_info *fb,
+	     struct file *file,
+	     struct vm_area_struct *vma)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	unsigned int len;
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+	u64 start=0, off;
+#else
+	unsigned long start=0, off;
+#endif
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+		DPRINTK("invalid vma->vm_pgoff\n");
+		return -EINVAL;
+	}
+    
+#ifdef SHADOW_FRAME_BUFFER
+	if (!info->shadow.fb) {
+		int order = 0;
+		while (info->fb_size > (PAGE_SIZE * (1 << order)))
+			order++;
+		info->shadow.fb = (void*)__get_free_pages(GFP_KERNEL, order);
+		if (!info->shadow.fb) {
+			DPRINTK("shadow fb alloc failed\n");
+			return -ENXIO;
+		}
+		memset(info->shadow.fb, 0, info->fb_size);
+		init_timer(&info->shadow.timer);
+		info->shadow.timer.function = do_write_shadow_fb;
+		info->shadow.timer.data = (unsigned long)info;
+	}
+	mod_timer(&info->shadow.timer, jiffies+HZ/2);
+	start = virt_to_phys(info->shadow.fb) & PAGE_MASK;
+#else
+	start = info->fix.membase_phys & PAGE_MASK;
+#endif
+
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fb_size);
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+    
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		DPRINTK("invalid vma\n");
+		return -EINVAL;
+	}
+
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+#ifdef SHADOW_FRAME_BUFFER
+	vma->vm_flags |= VM_RESERVED;
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_UNCACHED;
+#else
+	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
+#endif
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+	// FIXME: shouldn't have to do this. If the pages are marked writeable,
+	// the TLB fault handlers should set these.
+	pgprot_val(vma->vm_page_prot) |= (_PAGE_DIRTY | _PAGE_VALID);
+    
+	/*
+	 * The SED1356 has only a 16-bit wide data bus, and some
+	 * embedded platforms, such as the Pb1000, do not automatically
+	 * split 32-bit word accesses to the framebuffer into
+	 * seperate half-word accesses. Hence the upper half-word
+	 * never gets to the framebuffer. The following solution is
+	 * to intentionally return a non-32-bit-aligned VA. As long
+	 * as the user app assumes (and doesn't check) that the returned
+	 * VA is 32-bit aligned, all (assumed aligned) 32-bit accesses
+	 * will actually be unaligned and will get trapped by the MIPS
+	 * unaligned exception handler. This handler will emulate the
+	 * load/store instructions by splitting up the load/store
+	 * into two 16-bit load/stores. (This emulation is currently
+	 * enabled by default, but may be disabled in the future, when
+	 * alignment problems in user-level programs get fixed. When
+	 * that happens, this solution won't work anymore, unless the
+	 * process that mmap's the fb also calls sysmips(MIPS_FIXADE, 1),
+	 * which turns address-error emulation back on).
+	 *
+	 * Furthermore, this solution only seems to work for TinyX
+	 * (Xfbdev). Others, like Qt/E, do snoop the returned VA
+	 * and compensate, or do originally unaligned 32-bit accesses
+	 * which then become aligned, hence breaking this solution.
+	 */
+	if (info->fix.mmunalign)
+		vma->vm_start += 2;
+	
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+	if (e1356_remap_page_range(vma->vm_start, off,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+#else
+	if (io_remap_page_range(vma->vm_start, off,
+				vma->vm_end - vma->vm_start,
+				vma->vm_page_prot))
+		return -EAGAIN;
+#endif
+
+	info->mmaped = 1;
+	return 0;
+}
+
+
+int __init
+e1356fb_init(void)
+{
+	struct fb_var_screeninfo var;
+	struct e1356fb_fix * epfix = &fb_info.fix;
+	e1356_reg_t* reg;
+	void* regbase;
+	char* name = "SED1356";
+	int periodMCLK, periodBCLK;
+	int dram_timing, rr_div, mclk_src;
+	u8 rev_code, btmp, mclk_cfg;
+
+	if (options) {
+		e1356fb_setup(options, 0);
+	}
+
+	// clear out fb_info
+	memset(&fb_info, 0, sizeof(struct fb_info_e1356));
+
+	// copy boot options
+	fb_info.fix = boot_fix;
+	fb_info.default_par = boot_par;
+
+	fb_info.regbase_size = E1356_REG_SIZE;
+
+	if (!epfix->system) {
+		printk(KERN_ERR "e1356/86fb: no valid system found\n");
+		return -ENODEV;
+	}
+
+	if (epfix->system == SYS_SDU1356) {
+		// it's the SDU1356B0C PCI eval card.
+		struct pci_dev *pdev = NULL;
+		if (!pci_present())   /* No PCI bus in this machine! */
+			return -ENODEV;
+		if (!(pdev = pci_find_device(PCI_VENDOR_ID_EPSON,
+					     PCI_DEVICE_ID_EPSON_SDU1356, pdev)))
+			return -ENODEV;
+		if (pci_enable_device(pdev))
+			return -ENODEV;
+		epfix->regbase_phys = pci_resource_start(pdev, 0);
+		epfix->membase_phys = epfix->regbase_phys + E1356_REG_SIZE;
+	}
+	
+	fb_info.regbase_virt = ioremap_nocache(epfix->regbase_phys,
+					       E1356_REG_SIZE);
+
+	if (!fb_info.regbase_virt) {
+		printk("e1356fb: Can't remap %s register area.\n", name);
+		return -ENXIO;
+	}
+
+	regbase = fb_info.regbase_virt;
+	reg = &fb_info.reg;
+    
+	// Initialize the register pointers
+	reg->basic =         (reg_basic_t*)   (regbase + REG_BASE_BASIC);
+	reg->genio =         (reg_genio_t*)   (regbase + REG_BASE_GENIO);
+	reg->md_cfg =        (reg_mdcfg_t*)   (regbase + REG_BASE_MDCFG);
+	reg->clk_cfg =       (reg_clkcfg_t*)  (regbase + REG_BASE_CLKCFG);
+	reg->mem_cfg =       (reg_memcfg_t*)  (regbase + REG_BASE_MEMCFG);
+	reg->panel_cfg =     (reg_panelcfg_t*)(regbase + REG_BASE_PANELCFG);
+	reg->lcd_cfg =       (reg_dispcfg_t*) (regbase + REG_BASE_LCD_DISPCFG);
+	reg->crttv_cfg =     (reg_dispcfg_t*) (regbase + REG_BASE_CRTTV_DISPCFG);
+	reg->lcd_mode =      (reg_dispmode_t*)(regbase + REG_BASE_LCD_DISPMODE);
+	reg->crttv_mode =    (reg_dispmode_t*)(regbase + REG_BASE_CRTTV_DISPMODE);
+	reg->lcd_inkcurs =   (reg_inkcurs_t*) (regbase + REG_BASE_LCD_INKCURS);
+	reg->crttv_inkcurs = (reg_inkcurs_t*) (regbase + REG_BASE_CRTTV_INKCURS);
+	reg->bitblt =        (reg_bitblt_t*)  (regbase + REG_BASE_BITBLT);
+	reg->lut =           (reg_lut_t*)     (regbase + REG_BASE_LUT);
+	reg->pwr_save =      (reg_pwrsave_t*) (regbase + REG_BASE_PWRSAVE);
+	reg->misc =          (reg_misc_t*)    (regbase + REG_BASE_MISC);
+	reg->mediaplug =     (reg_mediaplug_t*)(regbase + REG_BASE_MEDIAPLUG);
+	reg->bitblt_data =   (u16*)           (regbase + REG_BASE_BITBLT_DATA);
+    
+	// Enable all register access
+	writeb(0, &reg->basic->misc);
+
+	rev_code = readb(&reg->basic->rev_code);
+	if ((rev_code >> 2) == 0x04) {
+		printk("Found EPSON1356 Display Controller\n");
+	}
+	else if ((rev_code >> 2) == 0x07) {
+		printk("Found EPSON13806 Display Controller\n");
+	}
+	else {
+		iounmap(fb_info.regbase_virt);
+		printk("e1356/806fb: %s not found, rev_code=0x%02x.\n",
+		       name, rev_code);
+		return -ENODEV;
+	}
+
+	fb_info.chip_rev = rev_code & 0x03;
+
+	// Determine frame-buffer size
+	switch (readb(&reg->md_cfg->md_cfg_stat0) >> 6) {
+	case 0:
+	case 2:
+		fb_info.fb_size = 0x80000;   /* 512K bytes */
+		break;
+	case 1:
+		if ((rev_code >> 2) == 7) /* 806 */
+			fb_info.fb_size = 0x140000;  /* 1.2M bytes */
+		else
+			fb_info.fb_size = 0x200000;  /* 2M bytes */
+		break;
+	default:
+		fb_info.fb_size = 0x200000;  /* 2M bytes */
+		break;
+	}
+
+	fb_info.membase_virt = ioremap_nocache(epfix->membase_phys,
+					       fb_info.fb_size);
+    
+	if (!fb_info.membase_virt) {
+		printk("e1356fb: Can't remap %s framebuffer.\n", name);
+		iounmap(fb_info.regbase_virt);
+		return -ENXIO;
+	}
+    
+	printk("e1356/806fb: Detected  %dKB framebuffer\n", 
+			(unsigned)fb_info.fb_size/1000);
+
+#ifdef CONFIG_MTRR
+	if (!epfix->nomtrr) {
+		fb_info.mtrr_idx = mtrr_add(epfix->membase_phys, fb_info.fb_size,
+					    MTRR_TYPE_WRCOMB, 1);
+		printk("e1356fb: MTRR's turned on\n");
+	}
+#endif
+    
+	if (!boot_fix.noaccel) {
+		/*
+		  Allocate a page for string BLTs. A 4K page is
+		  enough for a 256 character string at an 8x16 font.
+		*/
+		fb_info.putcs_buffer = (void*)__get_free_pages(GFP_KERNEL, 0);
+		if (fb_info.putcs_buffer == NULL) {
+			printk("e1356fb: Can't allocate putcs buffer\n");
+			goto unmap_ret_enxio;
+		}
+	}
+
+	// Begin SED1356 initialization
+
+	// disable display while initializing
+	writeb(0, &reg->misc->disp_mode);
+	// Set the GPIO1 and 2 to inputs
+	writeb(0, &reg->genio->gpio_cfg);
+	writeb(0, &reg->genio->gpio_ctrl);
+	if (fb_info.chip_rev == 7) /* 806 */
+		writeb(0, &reg->genio->gpio_ctrl2);
+
+	/*
+	 * Program the clocks
+	 */
+
+#ifdef CONFIG_MIPS_AU1000
+	if ((epfix->system == SYS_PB1000) || (epfix->system == SYS_PB1500))
+		epfix->busclk = get_au1000_lcd_clock();
+#endif
+	
+	if (epfix->busclk > 80000) {
+		printk("e1356fb: specified busclk too high\n");
+		goto ret_enxio;
+	}
+
+	epfix->mclk = mclk_cfg = 0;
+	if (epfix->system == SYS_PB1500) {
+		epfix->mclk = epfix->busclk;
+		mclk_cfg = 0x01;
+	}
+	else {
+		// Find the highest allowable MCLK
+		if (epfix->busclk <= MAX_PIXCLOCK && 
+				epfix->busclk > epfix->mclk) {
+			epfix->mclk = epfix->busclk;
+			mclk_cfg = 0x01;
+		}
+		if (epfix->clki <= MAX_PIXCLOCK && epfix->clki > epfix->mclk) {
+			epfix->mclk = epfix->clki;
+			mclk_cfg = 0x00;
+		}
+		if (epfix->busclk/2 <= MAX_PIXCLOCK && 
+				epfix->busclk/2 > epfix->mclk) {
+			epfix->mclk = epfix->busclk/2;
+			mclk_cfg = 0x11;
+		}
+		if (epfix->clki/2 <= MAX_PIXCLOCK && 
+				epfix->clki/2 > epfix->mclk) {
+			epfix->mclk = epfix->clki/2;
+			mclk_cfg = 0x10;
+		}
+	}
+	
+	if (!epfix->mclk) {
+		printk("e1356fb: couldn't find an allowable MCLK!\n");
+		goto ret_enxio;
+	}
+
+	// When changing mclk src, you must first set bit 4 to 1.
+	writeb(readb(&reg->clk_cfg->mem_clk_cfg) | 0x10,
+	       &reg->clk_cfg->mem_clk_cfg);
+	writeb(mclk_cfg, &reg->clk_cfg->mem_clk_cfg);
+
+	printk("e1356fb: clocks (kHz): busclk=%d mclk=%d clki=%d clki2=%d\n",
+	       epfix->busclk, epfix->mclk, epfix->clki, epfix->clki2);
+
+	// Set max pixel clock
+	switch (epfix->disp_type) {
+	case DISP_TYPE_LCD:
+	case DISP_TYPE_TFT:
+	case DISP_TYPE_CRT:
+		fb_info.max_pixclock = epfix->mclk;
+		break;
+	case DISP_TYPE_NTSC:
+	case DISP_TYPE_PAL:
+		fb_info.max_pixclock = (epfix->disp_type == DISP_TYPE_NTSC) ?
+			NTSC_PIXCLOCK : PAL_PIXCLOCK;
+		if (epfix->tv_filt & TV_FILT_FLICKER)
+			fb_info.max_pixclock *= 2;
+		break;
+	default:
+		printk("e1356fb: invalid specified display type\n");
+		goto ret_enxio;
+	}
+
+	periodMCLK = 1000000L / epfix->mclk;   // in nano-seconds
+	periodBCLK = 1000000L / epfix->busclk; // in nano-seconds
+	if (readb(&reg->md_cfg->md_cfg_stat1) & (1<<4))
+		periodBCLK *= 2;
+    
+	if ((epfix->system == SYS_PB1000) || (epfix->system == SYS_PB1500))
+		writeb(0x00, &reg->clk_cfg->cpu2mem_wait_sel);
+	else if (periodMCLK - 4 > periodBCLK)
+		writeb(0x02, &reg->clk_cfg->cpu2mem_wait_sel);
+	else if (2*periodMCLK - 4 > periodBCLK)
+		writeb(0x01, &reg->clk_cfg->cpu2mem_wait_sel);
+	else
+		writeb(0x00, &reg->clk_cfg->cpu2mem_wait_sel);
+
+	// Program memory config
+	if (epfix->mem_type < MEM_TYPE_EDO_2CAS ||
+	    epfix->mem_type > MEM_TYPE_EMBEDDED_SDRAM) {
+		printk("e1356fb: bad memory type specified\n");
+		goto ret_enxio;
+	}
+	writeb((u8)epfix->mem_type, &reg->mem_cfg->mem_cfg);
+
+	// calc closest refresh rate
+	rr_div = 7;
+	mclk_src = (mclk_cfg & 1) ? epfix->busclk : epfix->clki;
+	while ((mclk_src >> (6 + rr_div)) < epfix->mem_refresh)
+		if (--rr_div < 0) {
+			printk("e1356fb: can't set specified refresh rate\n");
+			goto ret_enxio;
+		}
+    
+	DPRINTK("refresh rate = %d kHz\n", (mclk_src >> (6 + rr_div)));
+
+	// add Suspend-Mode Refresh bits
+	if (epfix->mem_smr < MEM_SMR_CBR || epfix->mem_smr > MEM_SMR_NONE) {
+		printk("e1356fb: invalid specified suspend-mode refresh type\n");
+		goto ret_enxio;
+	}
+	writeb(rr_div | (epfix->mem_smr << 6), &reg->mem_cfg->dram_refresh);
+
+	// set DRAM speed
+	switch (epfix->mem_speed) {
+	case 50:
+		dram_timing = epfix->mclk >= 33000 ? 0x0101 : 0x0212;
+		break;
+	case 60:
+		if (epfix->mclk >= 30000)
+			dram_timing = 0x0101;
+		else if (epfix->mclk >= 25000)
+			dram_timing =
+				(epfix->mem_type == MEM_TYPE_EDO_2CAS ||
+				 epfix->mem_type == MEM_TYPE_EDO_2WE) ?
+				0x0212 : 0x0101;
+		else
+			dram_timing = 0x0212;
+		break;
+	case 70:
+		if (epfix->mclk >= 30000)
+			dram_timing = 0x0000;
+		else if (epfix->mclk >= 25000)
+			dram_timing = 0x0101;
+		else
+			dram_timing =
+				(epfix->mem_type == MEM_TYPE_EDO_2CAS ||
+				 epfix->mem_type == MEM_TYPE_EDO_2WE) ?
+				0x0212 : 0x0211;
+		break;
+	case 80:
+		if (epfix->mclk >= 25000)
+			dram_timing = 0x0100;
+		else
+			dram_timing = 0x0101;
+		break;
+	default:
+		printk("e1356fb: invalid specified memory speed\n");
+		goto ret_enxio;
+	}
+
+	writew(dram_timing, &reg->mem_cfg->dram_timings_ctrl0);
+    
+	currcon = -1;
+	if (!epfix->nohwcursor)
+		e1356fb_hwcursor_init(&fb_info);
+    
+	init_timer(&fb_info.cursor.timer);
+	fb_info.cursor.timer.function = do_flashcursor; 
+	fb_info.cursor.timer.data = (unsigned long)(&fb_info);
+	fb_info.cursor.state = CM_ERASE;
+	spin_lock_init(&fb_info.cursor.lock);
+    
+	strcpy(fb_info.fb_info.modename, "Epson "); 
+	strcat(fb_info.fb_info.modename, name);
+	fb_info.fb_info.changevar  = NULL;
+	fb_info.fb_info.node       = -1;
+
+	fb_info.fb_info.fbops      = &e1356fb_ops;
+	fb_info.fb_info.disp       = &fb_info.disp;
+	strcpy(fb_info.fb_info.fontname, epfix->fontname);
+	fb_info.fb_info.switch_con = &e1356fb_switch_con;
+	fb_info.fb_info.updatevar  = &e1356fb_updatevar;
+	fb_info.fb_info.blank      = &e1356fb_blank;
+	fb_info.fb_info.flags      = FBINFO_FLAG_DEFAULT;
+    
+	// Set-up display
+	// clear out unused stuff
+	writeb(0, &reg->panel_cfg->mod_rate);
+	writeb(0x01, &reg->lcd_mode->lcd_misc);
+	writeb(0, &reg->lcd_mode->fifo_high_thresh);
+	writeb(0, &reg->lcd_mode->fifo_low_thresh);
+	writeb(0, &reg->crttv_mode->fifo_high_thresh);
+	writeb(0, &reg->crttv_mode->fifo_low_thresh);
+    
+	switch (epfix->disp_type) {
+	case DISP_TYPE_LCD:
+		switch (epfix->panel_width) {
+		case 4: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x04); break;
+		case 8: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x14); break;
+		case 16: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x24); break;
+		default:
+			printk("e1356fb: invalid specified LCD panel data width\n");
+			goto ret_enxio;
+		}
+		writeb(btmp, &reg->panel_cfg->panel_type);
+		break;
+	case DISP_TYPE_TFT:
+		switch (epfix->panel_width) {
+		case 9: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x05); break;
+		case 12: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x15); break;
+		case 18: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x25); break;
+		default:
+			printk("e1356fb: invalid specified TFT panel data width\n");
+			goto ret_enxio;
+		}
+		writeb(btmp, &reg->panel_cfg->panel_type);
+		break;
+	case DISP_TYPE_CRT:
+		writeb(0x00, &reg->crttv_cfg->tv_output_ctrl);
+		break;
+	case DISP_TYPE_NTSC:
+	case DISP_TYPE_PAL:
+		if (epfix->tv_fmt < TV_FMT_COMPOSITE ||
+		    epfix->tv_fmt > TV_FMT_S_VIDEO) {
+			printk("e1356fb: invalid specified TV output format\n");
+			goto ret_enxio;
+		}
+		btmp = epfix->disp_type == DISP_TYPE_PAL ? 0x01 : 0x00;
+		btmp |= (epfix->tv_fmt == TV_FMT_S_VIDEO ? 0x02 : 0x00);
+		btmp |= ((epfix->tv_filt & TV_FILT_LUM) ? 0x10 : 0x00);
+		btmp |= ((epfix->tv_filt & TV_FILT_CHROM) ? 0x20 : 0x00);
+		writeb(btmp, &reg->crttv_cfg->tv_output_ctrl);
+		break;
+	}
+
+	memset(&var, 0, sizeof(var));
+	/*
+	 * If mode_option wasn't given at boot, assume all the boot
+	 * option timing parameters were specified individually, in
+	 * which case we convert par_to_var instead of calling
+	 * fb_find_mode.
+	 */
+	if (epfix->mode_option) {
+		struct fb_videomode* modedb, *dm;
+		int dbsize = e1356fb_get_mode(&fb_info, 640, 480, &modedb, &dm);
+
+		// first try the generic modedb
+		if (!fb_find_mode(&var, &fb_info.fb_info, epfix->mode_option,
+				  NULL, 0, NULL, boot_par.bpp)) {
+			printk("e1356fb: mode %s failed, trying e1356 modedb\n",
+			       epfix->mode_option);
+			// didn't work in generic modedb, try ours
+			if (!fb_find_mode(&var, &fb_info.fb_info,
+					  epfix->mode_option,
+					  modedb, dbsize, dm, boot_par.bpp)) {
+				printk("e1356fb: mode %s failed e1356 modedb too, sorry\n",
+				       epfix->mode_option);
+				
+				goto ret_enxio;
+			}
+		}
+
+		var.xres_virtual = boot_par.width_virt ?
+			boot_par.width_virt : boot_par.width;
+		var.yres_virtual = boot_par.height_virt ?
+			boot_par.height_virt : boot_par.height;
+	} else {
+		if (e1356fb_par_to_var(&var, &fb_info.default_par, &fb_info)) {
+			printk("e1356fb: boot option mode failed\n");
+			goto ret_enxio;
+		}
+	}
+    
+	if (boot_fix.noaccel)
+		var.accel_flags &= ~FB_ACCELF_TEXT;
+	else
+		var.accel_flags |= FB_ACCELF_TEXT;
+    
+	if (e1356fb_var_to_par(&var, &fb_info.default_par, &fb_info)) {
+		/*
+		 * Can't use the mode from the mode db or the default
+		 * mode or the boot options - give up
+		 */
+		printk("e1356fb: mode failed var_to_par\n");
+		goto ret_enxio;
+	}
+    
+	fb_info.disp.screen_base    = fb_info.membase_virt;
+	fb_info.disp.var            = var; // struct copy
+    
+	// here's where the screen is actually initialized and enabled
+	if (e1356fb_set_var(&var, -1, &fb_info.fb_info)) {
+		printk("e1356fb: can't set video mode\n");
+		goto ret_enxio;
+	}
+    
+	writeb(0, &reg->pwr_save->cfg);     // disable power-save mode
+	writeb(0, &reg->misc->cpu2mem_watchdog); // disable watchdog timer
+
+#ifdef E1356FB_VERBOSE_DEBUG
+	dump_fb(fb_info.membase_virt + 0x100000, 512);
+#endif
+
+	if (register_framebuffer(&fb_info.fb_info) < 0) {
+		writeb(0, &reg->misc->disp_mode); 
+		printk("e1356fb: can't register framebuffer\n");
+		goto ret_enxio;
+	}
+    
+	printk("fb%d: %s frame buffer device\n", 
+	       GET_FB_IDX(fb_info.fb_info.node),
+	       fb_info.fb_info.modename);
+    
+    
+	return 0;
+
+ ret_enxio:
+	free_pages((unsigned long)fb_info.putcs_buffer, 0);
+ unmap_ret_enxio:
+	iounmap(fb_info.regbase_virt);
+	iounmap(fb_info.membase_virt);
+	return -ENXIO;
+}
+
+/**
+ *	e1356fb_exit - Driver cleanup
+ *
+ *	Releases all resources allocated during the
+ *	course of the driver's lifetime.
+ *
+ *	FIXME - do results of fb_alloc_cmap need disposal?
+ */
+static void __exit
+e1356fb_exit (void)
+{
+	unregister_framebuffer(&fb_info.fb_info);
+	del_timer_sync(&fb_info.cursor.timer);
+
+#ifdef CONFIG_MTRR
+	if (!fb_info.fix.nomtrr) {
+		mtrr_del(fb_info.mtrr_idx, fb_info.fix.membase_phys,
+			 fb_info.fb_size);
+		printk("fb: MTRR's  turned off\n");
+	}
+#endif
+
+	free_pages((unsigned long)fb_info.putcs_buffer, 0);
+	iounmap(fb_info.regbase_virt);
+	iounmap(fb_info.membase_virt);
+}
+
+MODULE_AUTHOR("Steve Longerbeam <stevel@mvista.com>");
+MODULE_DESCRIPTION("SED1356 framebuffer device driver");
+
+#ifdef MODULE
+module_init(e1356fb_init);
+#endif
+module_exit(e1356fb_exit);
+
+
+void
+e1356fb_setup(char *options, int *ints)
+{
+	char* this_opt;
+    
+	memset(&boot_fix, 0, sizeof(struct e1356fb_fix));
+	memset(&boot_par, 0, sizeof(struct e1356fb_par));
+	boot_fix.system = -1;
+    
+	if (!options || !*options)
+		return;
+    
+	for(this_opt=strtok(options, ","); this_opt;
+	    this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "noaccel", 7)) {
+			boot_fix.noaccel = 1;
+		} else if (!strncmp(this_opt, "nopan", 5)) {
+			boot_fix.nopan = 1;
+		} else if (!strncmp(this_opt, "nohwcursor", 10)) {
+			boot_fix.nohwcursor = 1;
+		} else if (!strncmp(this_opt, "mmunalign:", 10)) {
+			boot_fix.mmunalign = simple_strtoul(this_opt+10,
+							    NULL, 0);
+#ifdef CONFIG_MTRR
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			boot_fix.nomtrr = 1;
+#endif
+		} else if (!strncmp(this_opt, "font:", 5)) {
+			strncpy(boot_fix.fontname, this_opt+5,
+				sizeof(boot_fix.fontname)-1);
+		} else if (!strncmp(this_opt, "regbase:", 8)) {
+			boot_fix.regbase_phys = simple_strtoul(this_opt+8,
+							       NULL, 0);
+		} else if (!strncmp(this_opt, "membase:", 8)) {
+			boot_fix.membase_phys = simple_strtoul(this_opt+8,
+							       NULL, 0);
+		} else if (!strncmp(this_opt, "memsp:", 6)) {
+			boot_fix.mem_speed = simple_strtoul(this_opt+6,
+							    NULL, 0);
+		} else if (!strncmp(this_opt, "memtyp:", 7)) {
+			boot_fix.mem_type = simple_strtoul(this_opt+7,
+							   NULL, 0);
+		} else if (!strncmp(this_opt, "memref:", 7)) {
+			boot_fix.mem_refresh = simple_strtoul(this_opt+7,
+							      NULL, 0);
+		} else if (!strncmp(this_opt, "memsmr:", 7)) {
+			boot_fix.mem_smr = simple_strtoul(this_opt+7, NULL, 0);
+		} else if (!strncmp(this_opt, "busclk:", 7)) {
+			boot_fix.busclk = simple_strtoul(this_opt+7, NULL, 0);
+		} else if (!strncmp(this_opt, "clki:", 5)) {
+			boot_fix.clki = simple_strtoul(this_opt+5, NULL, 0);
+		} else if (!strncmp(this_opt, "clki2:", 6)) {
+			boot_fix.clki2 = simple_strtoul(this_opt+6, NULL, 0);
+		} else if (!strncmp(this_opt, "display:", 8)) {
+			if (!strncmp(this_opt+8, "lcd", 3))
+				boot_fix.disp_type = DISP_TYPE_LCD;
+			else if (!strncmp(this_opt+8, "tft", 3))
+				boot_fix.disp_type = DISP_TYPE_TFT;
+			else if (!strncmp(this_opt+8, "crt", 3))
+				boot_fix.disp_type = DISP_TYPE_CRT;
+			else if (!strncmp(this_opt+8, "pal", 3))
+				boot_fix.disp_type = DISP_TYPE_PAL;
+			else if (!strncmp(this_opt+8, "ntsc", 4))
+				boot_fix.disp_type = DISP_TYPE_NTSC;
+		} else if (!strncmp(this_opt, "width:", 6)) {
+			boot_par.width = simple_strtoul(this_opt+6, NULL, 0);
+		} else if (!strncmp(this_opt, "height:", 7)) {
+			boot_par.height = simple_strtoul(this_opt+7, NULL, 0);
+		} else if (!strncmp(this_opt, "bpp:", 4)) {
+			boot_par.bpp = simple_strtoul(this_opt+4, NULL, 0);
+			boot_par.cmap_len = (boot_par.bpp == 8) ? 256 : 16;
+		} else if (!strncmp(this_opt, "elpanel:", 8)) {
+			boot_fix.panel_el = simple_strtoul(this_opt+8,
+							   NULL, 0);
+		} else if (!strncmp(this_opt, "pdataw:", 7)) {
+			boot_fix.panel_width = simple_strtoul(this_opt+7,
+							      NULL, 0);
+		} else if (!strncmp(this_opt, "hndp:", 5)) {
+			boot_par.horiz_ndp = simple_strtoul(this_opt+5,
+							    NULL, 0);
+		} else if (!strncmp(this_opt, "vndp:", 5)) {
+			boot_par.vert_ndp = simple_strtoul(this_opt+5,
+							   NULL, 0);
+		} else if (!strncmp(this_opt, "hspol:", 6)) {
+			boot_par.hsync_pol = simple_strtoul(this_opt+6,
+							    NULL, 0);
+		} else if (!strncmp(this_opt, "vspol:", 6)) {
+			boot_par.vsync_pol = simple_strtoul(this_opt+6,
+							    NULL, 0);
+		} else if (!strncmp(this_opt, "hsstart:", 8)) {
+			boot_par.hsync_start = simple_strtoul(this_opt+8,
+							      NULL, 0);
+		} else if (!strncmp(this_opt, "hswidth:", 8)) {
+			boot_par.hsync_width = simple_strtoul(this_opt+8,
+							      NULL, 0);
+		} else if (!strncmp(this_opt, "vsstart:", 8)) {
+			boot_par.vsync_start = simple_strtoul(this_opt+8,
+							      NULL, 0);
+		} else if (!strncmp(this_opt, "vswidth:", 8)) {
+			boot_par.vsync_width = simple_strtoul(this_opt+8,
+							      NULL, 0);
+		} else if (!strncmp(this_opt, "tvfilt:", 7)) {
+			boot_fix.tv_filt = simple_strtoul(this_opt+7, NULL, 0);
+		} else if (!strncmp(this_opt, "tvfmt:", 6)) {
+			boot_fix.tv_fmt = simple_strtoul(this_opt+6, NULL, 0);
+		} else if (!strncmp(this_opt, "system:", 7)) {
+			if (!strncmp(this_opt+7, "pb1000", 10)) {
+				boot_fix = systems[SYS_PB1000].fix;
+				boot_par = systems[SYS_PB1000].par;
+			} else if (!strncmp(this_opt+7, "pb1500", 7)) {
+				boot_fix = systems[SYS_PB1500].fix;
+				boot_par = systems[SYS_PB1500].par;
+			} else if (!strncmp(this_opt+7, "sdu1356", 7)) {
+				boot_fix = systems[SYS_SDU1356].fix;
+				boot_par = systems[SYS_SDU1356].par;
+			} else if (!strncmp(this_opt+7, "clio1050", 7)) {
+				boot_fix = systems[SYS_CLIO1050].fix;
+				boot_par = systems[SYS_CLIO1050].par;
+			}
+		} else {
+			boot_fix.mode_option = this_opt;
+		}
+	} 
+}
+
+
+/*
+ * FIXME: switching consoles could be dangerous. What if switching
+ * from a panel to a CRT/TV, or vice versa? More needs to be
+ * done here.
+ */
+static int
+e1356fb_switch_con(int con, struct fb_info *fb)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	struct e1356fb_par par;
+	int old_con = currcon;
+	int set_par = 1;
+
+	//DPRINTK("\n");
+
+	/* Do we have to save the colormap? */
+	if (currcon>=0)
+		if (fb_display[currcon].cmap.len)
+			fb_get_cmap(&fb_display[currcon].cmap, 1,
+				    e1356fb_getcolreg, fb);
+   
+	currcon = con;
+	fb_display[currcon].var.activate = FB_ACTIVATE_NOW; 
+	e1356fb_var_to_par(&fb_display[con].var, &par, info);
+	if (old_con>=0 && vt_cons[old_con]->vc_mode!=KD_GRAPHICS) {
+		/* check if we have to change video registers */
+		struct e1356fb_par old_par;
+		e1356fb_var_to_par(&fb_display[old_con].var, &old_par, info);
+		if (!memcmp(&par,&old_par,sizeof(par)))
+			set_par = 0;	/* avoid flicker */
+	}
+	if (set_par)
+		e1356fb_set_par(&par, info);
+    
+	if (fb_display[con].dispsw && fb_display[con].conp)
+		fb_con.con_cursor(fb_display[con].conp, CM_ERASE);
+   
+	del_timer(&(info->cursor.timer));
+	fb_info.cursor.state=CM_ERASE; 
+   
+	if (!info->fix.nohwcursor) 
+		if (fb_display[con].conp)
+			e1356fb_createcursor( &fb_display[con] );
+   
+	info->cursor.redraw=1;
+   
+	e1356fb_set_dispsw(&fb_display[con], 
+			   info, 
+			   par.bpp,
+			   fb_display[con].var.accel_flags & FB_ACCELF_TEXT);
+   
+	e1356fb_install_cmap(&fb_display[con], fb);
+	e1356fb_updatevar(con, fb);
+   
+	return 1;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+static void
+e1356fb_blank(int blank, struct fb_info *fb)
+{
+	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
+	reg_dispmode_t* dispmode = (IS_PANEL(info->fix.disp_type)) ?
+		info->reg.lcd_mode : info->reg.crttv_mode;
+	reg_pwrsave_t* pwrsave = info->reg.pwr_save;
+
+	//DPRINTK("\n");
+
+	switch (blank) {
+	case 0:
+		// Get out of power save mode
+		writeb(0x00, &pwrsave->cfg);
+		writeb(readb(&dispmode->disp_mode) & ~0x80,
+		       &dispmode->disp_mode);
+		break;
+	case 1:
+		// Get out of power save mode
+		writeb(0x00, &pwrsave->cfg);
+		writeb(readb(&dispmode->disp_mode) | 0x80,
+		       &dispmode->disp_mode);
+		break;
+		// No support for turning off horiz or vert sync, so just treat
+		// it as a power off.
+	case 2:
+	case 3:
+	case 4:
+		writeb(0x01, &pwrsave->cfg);
+		break;
+	}
+}
+
+
+static int
+e1356fb_updatevar(int con, struct fb_info* fb)
+{
+	struct fb_info_e1356* i = (struct fb_info_e1356*)fb;
+
+	//DPRINTK("\n");
+
+	if ((con==currcon) && (!i->fix.nopan)) 
+		do_pan_var(&fb_display[con].var,i);
+	return 0;
+}
+
+static int
+e1356fb_getcolreg(unsigned        regno, 
+		  unsigned*       red, 
+		  unsigned*       green,
+		  unsigned*       blue, 
+		  unsigned*       transp,
+		  struct fb_info* fb)
+{
+	struct fb_info_e1356* i = (struct fb_info_e1356*)fb;
+
+	if (regno > i->current_par.cmap_len)
+		return 1;
+   
+	*red    = i->palette[regno].red; 
+	*green  = i->palette[regno].green; 
+	*blue   = i->palette[regno].blue; 
+	*transp = 0;
+   
+	return 0;
+}
+
+static int
+e1356fb_setcolreg(unsigned        regno, 
+		  unsigned        red, 
+		  unsigned        green,
+		  unsigned        blue, 
+		  unsigned        transp,
+		  struct fb_info* info)
+{
+	struct fb_info_e1356* i = (struct fb_info_e1356*)info;
+
+	if (regno > 255)
+		return 1;
+
+	i->palette[regno].red    = red;
+	i->palette[regno].green  = green;
+	i->palette[regno].blue   = blue;
+   
+	switch(i->current_par.bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		do_setpalentry(i->reg.lut, regno,
+			       (u8)(red>>8), (u8)(green>>8), (u8)(blue>>8));
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		i->fbcon_cmap16[regno] = (regno << 10) | (regno << 5) | regno;
+		break;
+#endif
+	default:
+		DPRINTK("bad depth %u\n", i->current_par.bpp);
+		break;
+	}
+	return 0;
+}
+
+static void
+e1356fb_install_cmap(struct display *d, struct fb_info *info) 
+{
+	struct fb_info_e1356* i = (struct fb_info_e1356*)info;
+
+	//DPRINTK("\n");
+
+	if (d->cmap.len) {
+		fb_set_cmap(&(d->cmap), 1, e1356fb_setcolreg, info);
+	} else {
+		fb_set_cmap(fb_default_cmap(i->current_par.cmap_len), 1,
+			    e1356fb_setcolreg, info);
+	}
+}
+
+static void
+e1356fb_createcursorshape(struct display* p) 
+{
+	int h,u;
+   
+	h = fontheight(p);
+
+	fb_info.cursor.type = p->conp->vc_cursor_type & CUR_HWMASK;
+
+	switch (fb_info.cursor.type) {
+	case CUR_NONE: 
+		u = h; 
+		break;
+	case CUR_UNDERLINE: 
+		u = h - 2; 
+		break;
+	case CUR_LOWER_THIRD: 
+		u = (h * 2) / 3; 
+		break;
+	case CUR_LOWER_HALF: 
+		u = h / 2; 
+		break;
+	case CUR_TWO_THIRDS: 
+		u = h / 3; 
+		break;
+	case CUR_BLOCK:
+	default:
+		u = 0;
+		break;
+	}
+    
+	fb_info.cursor.w = fontwidth_x8(p);
+	fb_info.cursor.u = u;
+	fb_info.cursor.h = h;
+}
+   
+static void
+e1356fb_createcursor(struct display *p)
+{
+	void* memcursor;
+	int y, w, h, u;
+    
+	e1356fb_createcursorshape(p);
+
+	h = fb_info.cursor.h;
+	w = fb_info.cursor.w;
+	u = fb_info.cursor.u;
+	memcursor = fb_info.membase_virt + fb_info.fb_size;
+
+	// write cursor to display memory
+	for (y=0; y<64; y++) {
+		if (y >= h || y < u) {
+			fbfill((u16*)memcursor, 0xaa, 16); // b/g
+		} else {
+			fbfill((u16*)memcursor, 0xff, w/4); // inverted b/g
+			fbfill((u16*)memcursor + w/4, 0xaa, (64 - w)/4); // b/g
+		}
+		memcursor += 16;
+	}
+}
+   
+static void
+e1356fb_hwcursor_init(struct fb_info_e1356* info)
+{
+	reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ?
+		info->reg.lcd_inkcurs : info->reg.crttv_inkcurs;
+
+	fb_info.fb_size -= 1024;
+	// program cursor base address
+	writeb(0x00, &inkcurs->start_addr);
+	printk("e1356fb: reserving 1024 bytes for the hwcursor at %p\n",
+	       fb_info.membase_virt + fb_info.fb_size);
+}
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+
+/*
+ * Return indicates whether a page was freed so caller can adjust rss
+ */
+static inline void forget_pte(pte_t page)
+{
+	if (!pte_none(page)) {
+		printk("forget_pte: old mapping existed!\n");
+		BUG();
+	}
+}
+
+/*
+ * maps a range of physical memory into the requested pages. the old
+ * mappings are removed. any references to nonexistent pages results
+ * in null mappings (currently treated as "copy-on-access")
+ */
+static inline void e1356_remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long end;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	do {
+		struct page *page;
+		pte_t oldpage;
+		oldpage = ptep_get_and_clear(pte);
+
+		page = virt_to_page(__va(phys_addr));
+		if ((!VALID_PAGE(page)) || PageReserved(page))
+ 			set_pte(pte, mk_pte_phys(phys_addr, prot));
+		forget_pte(oldpage);
+		address += PAGE_SIZE;
+		phys_addr += PAGE_SIZE;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int e1356_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	do {
+		pte_t * pte = pte_alloc(mm, pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		e1356_remap_pte_range(pte, address, end - address, address + phys_addr, prot);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+/*  Note: this is only safe if the mm semaphore is held when called. */
+static int e1356_remap_page_range(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot)
+{
+	int error = 0;
+	pgd_t * dir;
+	phys_t beg = from;
+	phys_t end = from + size;
+	struct mm_struct *mm = current->mm;
+
+	phys_addr -= from;
+	dir = pgd_offset(mm, from);
+	flush_cache_range(mm, beg, end);
+	if (from >= end)
+		BUG();
+
+	spin_lock(&mm->page_table_lock);
+	do {
+		pmd_t *pmd = pmd_alloc(mm, dir, from);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = e1356_remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
+		if (error)
+			break;
+		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (from && (from < end));
+	spin_unlock(&mm->page_table_lock);
+	flush_tlb_range(mm, beg, end);
+	return error;
+}
+#endif
diff -urN linux-2.4.20-pre6/drivers/video/epson1356fb.h linux-2.4.20-pre7/drivers/video/epson1356fb.h
--- linux-2.4.20-pre6/drivers/video/epson1356fb.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/drivers/video/epson1356fb.h	Thu Sep 12 20:01:48 2002
@@ -0,0 +1,646 @@
+/*
+ *      epson1356fb.h  --  Epson SED1356 Framebuffer 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.
+ */
+
+#ifdef E1356FB_DEBUG
+#define DPRINTK(a,b...) printk(KERN_DEBUG "e1356fb: %s: " a, __FUNCTION__ , ## b)
+#else
+#define DPRINTK(a,b...)
+#endif 
+
+#define E1356_REG_SIZE  0x200000
+
+#define PICOS2KHZ(a) (1000000000UL/(a))
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+#define MAX_PIXCLOCK  40000 // KHz
+#define NTSC_PIXCLOCK 14318 // KHz
+#define PAL_PIXCLOCK  17734 // KHz
+
+/*
+ * Maximum percent errors between desired pixel clock and
+ * supported pixel clock. Lower-than and higher-than desired
+ * clock percent errors.
+ */
+#define MAX_PCLK_ERROR_LOWER  10
+#define MAX_PCLK_ERROR_HIGHER -1
+
+#define fontwidth_x8(p) (((fontwidth(p) + 7) >> 3) << 3)
+
+/*
+ * Register Structures
+ */
+
+// Basic
+#define REG_BASE_BASIC     0x00
+typedef struct {
+	u8 rev_code;           // 00
+	u8 misc;               // 01
+} reg_basic_t;
+
+// General IO Pins
+#define REG_BASE_GENIO     0x04
+typedef struct {
+	u8 gpio_cfg;           // 04
+	u8 gpio_cfg2;          // 05 SED13806
+	u8 spacer[2];          // 06
+	u8 gpio_ctrl;          // 08
+	u8 gpio_ctrl2;         // 09 SED13806
+} reg_genio_t;
+
+// MD Config Readback
+#define REG_BASE_MDCFG     0x0c
+typedef struct {
+	u8 md_cfg_stat0;       // 0C
+	u8 md_cfg_stat1;       // 0D
+} reg_mdcfg_t;
+
+// Clock Config
+#define REG_BASE_CLKCFG    0x10
+typedef struct {
+	u8 mem_clk_cfg;        // 10
+	u8 spacer1[3];         // 11
+	u8 lcd_pclk_cfg;       // 14
+	u8 spacer2[3];         // 15
+	u8 crttv_pclk_cfg;     // 18
+	u8 spacer3[3];         // 19
+	u8 mpclk_cfg;          // 1C
+	u8 spacer4;            // 1D
+	u8 cpu2mem_wait_sel;   // 1E
+} reg_clkcfg_t;
+
+// Memory Config
+#define REG_BASE_MEMCFG    0x20
+typedef struct {
+	u8 mem_cfg;            // 20
+	u8 dram_refresh;       // 21
+	u8 spacer[8];          // 22
+	u8 dram_timings_ctrl0; // 2A
+	u8 dram_timings_ctrl1; // 2B
+} reg_memcfg_t;
+
+// Panel Config
+#define REG_BASE_PANELCFG  0x30
+typedef struct {
+	u8 panel_type;         // 30
+	u8 mod_rate;           // 31
+} reg_panelcfg_t;
+
+// LCD and CRTTV Display Config
+#define REG_BASE_LCD_DISPCFG   0x32
+#define REG_BASE_CRTTV_DISPCFG 0x50
+typedef struct {
+	u8 hdw;                // 32 or 50
+	u8 spacer1;            // 33 or 51
+	u8 hndp;               // 34 or 52
+	u8 hsync_start;        // 35 or 53
+	u8 hsync_pulse;        // 36 or 54
+	u8 spacer2;            // 37 or 55
+	u8 vdh0;               // 38 or 56
+	u8 vdh1;               // 39 or 57
+	u8 vndp;               // 3A or 58
+	u8 vsync_start;        // 3B or 59
+	u8 vsync_pulse;        // 3C or 5A
+	u8 tv_output_ctrl;     // 5B (TV only)
+} reg_dispcfg_t;
+
+// LCD and CRTTV Display Mode
+#define REG_BASE_LCD_DISPMODE   0x40
+#define REG_BASE_CRTTV_DISPMODE 0x60
+typedef struct {
+	u8 disp_mode;          // 40 or 60
+	u8 lcd_misc;           // 41 (LCD only)
+	u8 start_addr0;        // 42 or 62
+	u8 start_addr1;        // 43 or 63
+	u8 start_addr2;        // 44 or 64
+	u8 spacer1;            // 45 or 65
+	u8 mem_addr_offset0;   // 46 or 66
+	u8 mem_addr_offset1;   // 47 or 67
+	u8 pixel_panning;      // 48 or 68
+	u8 spacer2;            // 49 or 69
+	u8 fifo_high_thresh;   // 4A or 6A
+	u8 fifo_low_thresh;    // 4B or 6B
+} reg_dispmode_t;
+
+// LCD and CRTTV Ink/Cursor
+#define REG_BASE_LCD_INKCURS   0x70
+#define REG_BASE_CRTTV_INKCURS 0x80
+typedef struct {
+	u8 ctrl;               // 70 or 80
+	u8 start_addr;         // 71 or 81
+	u8 x_pos0;             // 72 or 82
+	u8 x_pos1;             // 73 or 83
+	u8 y_pos0;             // 74 or 84
+	u8 y_pos1;             // 75 or 85
+	u8 blue0;              // 76 or 86
+	u8 green0;             // 77 or 87
+	u8 red0;               // 78 or 88
+	u8 spacer1;            // 79 or 89
+	u8 blue1;              // 7A or 8A
+	u8 green1;             // 7B or 8B
+	u8 red1;               // 7C or 8C
+	u8 spacer2;            // 7D or 8D
+	u8 fifo;               // 7E or 8E
+} reg_inkcurs_t;
+
+// BitBlt Config
+#define REG_BASE_BITBLT        0x100
+typedef struct {
+	u8 ctrl0;              // 100
+	u8 ctrl1;              // 101
+	u8 rop_code;           // 102
+	u8 operation;          // 103
+	u8 src_start_addr0;    // 104
+	u8 src_start_addr1;    // 105
+	u8 src_start_addr2;    // 106
+	u8 spacer1;            // 107
+	u8 dest_start_addr0;   // 108
+	u8 dest_start_addr1;   // 109
+	u8 dest_start_addr2;   // 10A
+	u8 spacer2;            // 10B
+	u8 mem_addr_offset0;   // 10C
+	u8 mem_addr_offset1;   // 10D
+	u8 spacer3[2];         // 10E
+	u8 width0;             // 110
+	u8 width1;             // 111
+	u8 height0;            // 112
+	u8 height1;            // 113
+	u8 bg_color0;          // 114
+	u8 bg_color1;          // 115
+	u8 spacer4[2];         // 116
+	u8 fg_color0;          // 118
+	u8 fg_color1;          // 119
+} reg_bitblt_t;
+
+// LUT
+#define REG_BASE_LUT           0x1e0
+typedef struct {
+	u8 mode;               // 1E0
+	u8 spacer1;            // 1E1
+	u8 addr;               // 1E2
+	u8 spacer2;            // 1E3
+	u8 data;               // 1E4
+} reg_lut_t;
+
+// Power Save Config
+#define REG_BASE_PWRSAVE       0x1f0
+typedef struct {
+	u8 cfg;                // 1F0
+	u8 status;             // 1F1
+} reg_pwrsave_t;
+
+// Misc
+#define REG_BASE_MISC          0x1f4
+typedef struct {
+	u8 cpu2mem_watchdog;   // 1F4
+	u8 spacer[7];          // 1F5
+	u8 disp_mode;          // 1FC
+} reg_misc_t;
+
+// MediaPlug
+#define REG_BASE_MEDIAPLUG     0x1000
+typedef struct {
+	u8 lcmd;               // 1000
+	u8 spacer1;            // 1001
+	u8 reserved_lcmd;      // 1002
+	u8 spacer2;            // 1003
+	u8 cmd;                // 1004
+	u8 spacer3;            // 1005
+	u8 reserved_cmd;       // 1006
+	u8 spacer4;            // 1007
+	u8 data;               // 1008
+} reg_mediaplug_t;
+
+// BitBlt data register. 16-bit access only
+#define REG_BASE_BITBLT_DATA   0x100000
+
+typedef struct {
+	reg_basic_t* basic;
+	reg_genio_t* genio;
+	reg_mdcfg_t* md_cfg;
+	reg_clkcfg_t* clk_cfg;
+	reg_memcfg_t* mem_cfg;
+	reg_panelcfg_t* panel_cfg;
+	reg_dispcfg_t* lcd_cfg;
+	reg_dispcfg_t* crttv_cfg;
+	reg_dispmode_t* lcd_mode;
+	reg_dispmode_t* crttv_mode;
+	reg_inkcurs_t* lcd_inkcurs;
+	reg_inkcurs_t* crttv_inkcurs;
+	reg_bitblt_t* bitblt;
+	reg_lut_t* lut;
+	reg_pwrsave_t* pwr_save;
+	reg_misc_t* misc;
+	reg_mediaplug_t* mediaplug;
+	u16* bitblt_data;
+} e1356_reg_t;
+
+
+/*--------------------------------------------------------*/
+
+enum mem_type_t {
+	MEM_TYPE_EDO_2CAS = 0,
+	MEM_TYPE_FPM_2CAS,
+	MEM_TYPE_EDO_2WE,
+	MEM_TYPE_FPM_2WE,
+	MEM_TYPE_EMBEDDED_SDRAM = 0x80
+};
+
+enum mem_smr_t {
+	MEM_SMR_CBR = 0,
+	MEM_SMR_SELF,
+	MEM_SMR_NONE
+};
+
+enum disp_type_t {
+	DISP_TYPE_LCD = 0,
+	DISP_TYPE_TFT,
+	DISP_TYPE_CRT,
+	DISP_TYPE_PAL,
+	DISP_TYPE_NTSC
+};
+
+/*
+ * Maximum timing values, as determined by the SED1356 register
+ * field sizes. All are indexed by display type, except
+ * max_hsync_start which is first indexed by color depth,
+ * then by display type.
+ */
+static const int max_hndp[5] = {256, 256, 512, 511, 510};
+static const int max_hsync_start[2][5] = {
+	{0, 252, 507, 505, 505}, // 8 bpp
+	{0, 254, 509, 507, 507}  // 16 bpp
+};
+static const int max_hsync_width[5] = {0, 128, 128, 0, 0};
+static const int max_vndp[5] = {64, 64, 128, 128, 128};
+static const int max_vsync_start[5] = {0, 64, 128, 128, 128};
+static const int max_vsync_width[5] = {0, 8, 8, 0, 0};
+
+#define IS_PANEL(disp_type) \
+    (disp_type == DISP_TYPE_LCD || disp_type == DISP_TYPE_TFT)
+#define IS_CRT(disp_type) (disp_type == DISP_TYPE_CRT)
+#define IS_TV(disp_type) \
+    (disp_type == DISP_TYPE_NTSC || disp_type == DISP_TYPE_PAL)
+
+
+enum tv_filters_t {
+	TV_FILT_LUM = 1,
+	TV_FILT_CHROM = 2,
+	TV_FILT_FLICKER = 4
+};
+
+enum tv_format_t {
+	TV_FMT_COMPOSITE = 0,
+	TV_FMT_S_VIDEO
+};
+
+
+struct e1356fb_fix {
+	int system;       // the number of a pre-packaged system
+	u64 regbase_phys; // phys start address of registers
+	u64 membase_phys; // phys start address of fb memory
+
+	// Memory parameters
+	int mem_speed;    // speed: 50, 60, 70, or 80 (nsec)
+	int mem_type;     // mem type: EDO-2CAS, FPM-2CAS, EDO-2WE, FPM-2WE
+	int mem_refresh;  // refresh rate in KHz
+	int mem_smr;      // suspend mode refresh: CAS_BEFORE_RAS, SELF, or NONE
+	// Clocks
+	int busclk;       // BUSCLK frequency, in KHz
+	int mclk;         // MCLK freq, in KHz, will either be BUSCLK or BUSCLK/2
+	int clki;         // CLKI frequency, in KHz
+	int clki2;        // CLKI2 frequency, in KHz
+
+	int disp_type;    // LCD, TFT, CRT, PAL, or NTSC
+
+	// TV Options
+	u8  tv_filt;      // TV Filter mask, LUM, CHROM, and FLICKER
+	int tv_fmt;       // TV output format, COMPOSITE or S_VIDEO
+    
+	// Panel (LCD,TFT) Options
+	int panel_el;     // enable support for EL-type panels
+	int panel_width;  // Panel data width: LCD: 4/8/16, TFT: 9/12/18
+    
+	// Misc
+	int noaccel;
+	int nopan;
+#ifdef CONFIG_MTRR
+	int nomtrr;
+#endif
+	int nohwcursor;
+	int mmunalign;    // force unaligned returned VA in mmap()
+	char fontname[40];
+
+	char *mode_option;
+};
+
+
+typedef struct {
+	int pixclk_d;     // Desired Pixel Clock, KHz
+	int pixclk;       // Closest supported clock to desired clock, KHz
+	int error;        // percent error between pixclock and pixclock_d
+	int clksrc;       // equal to busclk, mclk, clki, or clki2, KHz
+	int divisor;      // pixclk = clksrc/divisor, where divisor = 1,2,3, or 4
+	u8  pixclk_bits;  // pixclock register value for above settings
+} pixclock_info_t;
+
+
+struct e1356fb_par {
+	int width;
+	int height;
+	int width_virt;   // Width in pixels
+	int height_virt;  // Height in lines
+	int bpp;          // bits-per-pixel
+	int Bpp;          // Bytes-per-pixel
+
+	// Timing
+	pixclock_info_t ipclk;
+	int horiz_ndp;    // Horiz. Non-Display Period, pixels
+	int vert_ndp;     // Vert. Non-Display Period, lines
+	int hsync_pol;    // Polarity of horiz. sync signal (HRTC for CRT/TV,
+	// FPLINE for TFT). 0=active lo, 1=active hi
+	int hsync_start;  // Horiz. Sync Start position, pixels
+	int hsync_width;  // Horiz. Sync Pulse width, pixels
+	int hsync_freq;   // calculated horizontal sync frequency
+	int vsync_pol;    // Polarity of vert. sync signal (VRTC for CRT/TV,
+	// FPFRAME for TFT). 0=active lo, 1=active hi
+	int vsync_start;  // Vert. Sync Start position, lines
+	int vsync_width;  // Vert. Sync Pulse width, lines
+	int vsync_freq;   // calculated vertical sync frequency
+
+	int cmap_len;     // color-map length
+};
+
+
+
+struct fb_info_e1356 {
+	struct fb_info fb_info;
+
+	void *regbase_virt;
+	unsigned long regbase_size;
+	void *membase_virt;
+	unsigned long fb_size;
+
+	e1356_reg_t reg;
+
+	void* putcs_buffer;
+    
+	int max_pixclock;   // Max supported pixel clock, KHz
+	int open, mmaped;   // open count, is mmap'ed
+	
+	u8 chip_rev;
+    
+#ifdef CONFIG_MTRR
+	int mtrr_idx;
+#endif
+
+#ifdef SHADOW_FRAME_BUFFER
+	struct {
+		void* fb;
+		struct timer_list timer;
+	} shadow;
+#endif
+
+	struct { unsigned red, green, blue, pad; } palette[256];
+	struct display disp;
+
+#if defined(FBCON_HAS_CFB16)
+	u16 fbcon_cmap16[16];
+#endif
+    
+	struct {
+		int type;
+		int state;
+		int w,h,u;
+		int x,y,redraw;
+		unsigned long enable,disable;
+		struct timer_list timer;
+		spinlock_t lock; 
+	} cursor;
+ 
+	struct e1356fb_fix fix;
+	struct e1356fb_par default_par;
+	struct e1356fb_par current_par;
+};
+
+
+// The following are boot options for particular SED1356-based target systems
+
+enum {
+	SYS_NULL,
+	SYS_PB1000,
+	SYS_PB1500,
+	SYS_SDU1356,
+	SYS_CLIO1050,
+	NUM_SYSTEMS // must be last
+};
+
+static struct {
+	struct e1356fb_fix fix;
+	struct e1356fb_par par;
+} systems[NUM_SYSTEMS] = {
+
+	/*
+	 * NULL system to help us detect missing options
+ 	 * when the driver is compiled as a module.
+	 */
+	{
+		{   // fix
+			SYS_NULL,
+		},
+		{   // par
+		}
+	},
+
+	/*
+	 * Alchemy Pb1000 evaluation board, SED1356
+	 */
+	{
+		{   // fix
+			SYS_PB1000,
+			/*
+			 * Note!: these are "pseudo" physical addresses;
+			 * the SED1356 is not actually mapped here, but rather
+			 * at the 36-bit address of 0xE 0000 0000. There is an
+			 * ugly hack in the Au1000 TLB refill handler that will
+			 * translate pte_t's in the range 0xE000 0000 -->
+			 * 0xEFFF FFFF to the 36-bit range 0xE 0000 0000 -->
+			 * 0xE 0FFF FFFF. The long-term solution is to support
+			 * 36-bit physical addresses in linux-mips32 mm, since
+			 * the mips32 specification specifically supports this.
+			 */
+			0xE00000000, 0xE00200000,
+			60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
+			0, 0,   // BUSCLK and MCLK are calculated at run-time
+			40000, 14318, // CLKI, CLKI2
+#ifdef CONFIG_PB1000_CRT
+			DISP_TYPE_CRT,
+			0, 0, // TV Options
+			0, 0, // Panel options
+#elif defined (CONFIG_PB1000_NTSC)
+			DISP_TYPE_NTSC,
+			TV_FILT_FLICKER|TV_FILT_LUM|TV_FILT_CHROM,
+			TV_FMT_COMPOSITE,
+			0, 0, // Panel options
+#elif defined (CONFIG_PB1000_TFT)
+			DISP_TYPE_TFT,
+			0, 0, // TV Options
+			0, 12, // Panel options, EL panel?, data width?
+#else
+			DISP_TYPE_PAL,
+			TV_FILT_FLICKER|TV_FILT_LUM|TV_FILT_CHROM,
+			TV_FMT_COMPOSITE,
+			0, 0, // Panel options
+#endif
+			0, 0,
+#ifdef CONFIG_MTRR
+			0,
+#endif
+			0,
+			0,
+			{0},
+			"800x600@60"
+		},
+		{   // par
+			0, 0, 800, 600, 8, 1,
+			// timings will be set by modedb
+			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			256
+		}
+	},
+
+	/*
+	 * Alchemy Pb1500 evaluation board, SED13806
+	 */
+	{
+		{   // fix
+			SYS_PB1500,
+			/*
+			 * Note!: these are "pseudo" physical addresses;
+			 * the SED1356 is not actually mapped here, but rather
+			 * at the 36-bit address of 0xE 0000 0000. There is an
+			 * ugly hack in the Au1000 TLB refill handler that will
+			 * translate pte_t's in the range 0xE000 0000 -->
+			 * 0xEFFF FFFF to the 36-bit range 0xE 0000 0000 -->
+			 * 0xE 0FFF FFFF. The long-term solution is to support
+			 * 36-bit physical addresses in linux-mips32 mm, since
+			 * the mips32 specification specifically supports this.
+			 */
+			0xE1B000000, 0xE1B200000,
+			50, MEM_TYPE_EMBEDDED_SDRAM, 64, MEM_SMR_CBR,
+			0, 0,   // BUSCLK and MCLK are calculated at run-time
+			40000, 14318, // CLKI, CLKI2
+#ifdef CONFIG_PB1500_CRT
+			DISP_TYPE_CRT,
+			0, 0, // TV Options
+			0, 0, // Panel options
+#else
+			DISP_TYPE_TFT,
+			0, 0, // TV Options
+			0, 12, // Panel options, EL panel?, data width?
+#endif
+			0, 0,
+#ifdef CONFIG_MTRR
+			0,
+#endif
+			0,
+			0,
+			{0},
+			"800x600@60"
+		},
+		{   // par
+			0, 0, 800, 600, 8, 1,
+			// timings will be set by modedb
+			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			256
+		}
+	},
+
+	/*
+	 * Epson SDU1356B0C PCI eval card. These settings assume the
+	 * card is configured for PCI, the MediaPlug is disabled,
+	 * and the onboard clock synthesizer is at the power-up
+	 * clock settings.
+	 */
+	{
+		{   // fix
+			SYS_SDU1356,
+			0x0, 0x0,  // addresses obtained from PCI config space
+			// FIXME: just guess for now
+			60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
+			33000, 0, 40000, 25175, // BUSCLK, MCLK, CLKI, CLKI2
+			DISP_TYPE_CRT,
+			0, 0,
+			0, 0,
+			0, 0,
+#ifdef CONFIG_MTRR
+			0,
+#endif
+			0,
+			0,
+			{0},
+			"800x600@60"
+		},
+		{   // par
+			0, 0, 1024, 768, 8, 1,
+			// timings will be set by modedb
+			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			256
+		}
+	},
+
+	/*
+	 * Vadem Clio 1050 - this is for the benefit of the Linux-VR project.
+	 * FIXME: Most of these settings are just guesses, until I can get a
+	 * Clio 1050 and dump the registers that WinCE has setup.
+	 */
+	{
+		{   // fix
+			SYS_CLIO1050,
+			0x0a000000, 0x0a200000,
+			60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
+			40000, 40000, 14318, 14318,
+			DISP_TYPE_TFT,
+			0, 0,
+			0, 16,
+			0, 0,
+#ifdef CONFIG_MTRR
+			0,
+#endif
+			0,
+			0,
+			{0},
+			"640x480@85"
+		},
+		{   // par
+			0, 0, 1024, 768, 16, 2,
+			// timings will be set by modedb
+			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			16
+		}
+	}
+};
diff -urN linux-2.4.20-pre6/drivers/video/fbcon.c linux-2.4.20-pre7/drivers/video/fbcon.c
--- linux-2.4.20-pre6/drivers/video/fbcon.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/video/fbcon.c	Thu Sep 12 20:01:48 2002
@@ -637,7 +637,7 @@
     }
     
     if (!fontwidthvalid(p,fontwidth(p))) {
-#ifdef CONFIG_FBCON_MAC
+#if defined(CONFIG_FBCON_MAC) && defined(CONFIG_MAC)
 	if (MACH_IS_MAC)
 	    /* ++Geert: hack to make 6x11 fonts work on mac */
 	    p->dispsw = &fbcon_mac;
diff -urN linux-2.4.20-pre6/drivers/video/fbmem.c linux-2.4.20-pre7/drivers/video/fbmem.c
--- linux-2.4.20-pre6/drivers/video/fbmem.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/drivers/video/fbmem.c	Thu Sep 12 20:01:48 2002
@@ -132,6 +132,8 @@
 extern int radeonfb_setup(char*);
 extern int e1355fb_init(void);
 extern int e1355fb_setup(char*);
+extern int au1100fb_init(void);
+extern int au1100fb_setup(char*);
 extern int pvr2fb_init(void);
 extern int pvr2fb_setup(char*);
 extern int sstfb_init(void);
@@ -310,6 +312,9 @@
 #ifdef CONFIG_FB_MAXINE
 	{ "maxinefb", maxinefb_init, NULL },
 #endif
+#ifdef CONFIG_FB_AU1100
+	{ "au1100fb", au1100fb_init, au1100fb_setup },
+#endif 
 
 
 	/*
diff -urN linux-2.4.20-pre6/drivers/video/newport_con.c linux-2.4.20-pre7/drivers/video/newport_con.c
--- linux-2.4.20-pre6/drivers/video/newport_con.c	Mon Oct 15 13:47:24 2001
+++ linux-2.4.20-pre7/drivers/video/newport_con.c	Thu Sep 12 20:01:48 2002
@@ -36,6 +36,7 @@
 #define LOGO_H		80
 
 extern struct fbcon_font_desc font_vga_8x16;
+extern unsigned long sgi_gfxaddr;
 
 #define FONT_DATA ((unsigned char *)font_vga_8x16.data)
 
@@ -290,8 +291,9 @@
 	int i;
 	struct newport_regs *p;
 
-	npregs = (struct newport_regs *) (KSEG1 + 0x1f0f0000);
-
+	if (!sgi_gfxaddr)
+		return NULL;
+	npregs = (struct newport_regs *) (KSEG1 + sgi_gfxaddr);
 	p = npregs;
 	p->cset.config = NPORT_CFG_GD0;
 
diff -urN linux-2.4.20-pre6/drivers/video/tx3912fb.c linux-2.4.20-pre7/drivers/video/tx3912fb.c
--- linux-2.4.20-pre6/drivers/video/tx3912fb.c	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/drivers/video/tx3912fb.c	Thu Sep 12 20:01:48 2002
@@ -10,6 +10,7 @@
  *
  *  Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
  */
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
diff -urN linux-2.4.20-pre6/drivers/video/tx3912fb.h linux-2.4.20-pre7/drivers/video/tx3912fb.h
--- linux-2.4.20-pre6/drivers/video/tx3912fb.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/drivers/video/tx3912fb.h	Thu Sep 12 20:01:48 2002
@@ -9,6 +9,7 @@
  *
  *  Includes for TMPR3912/05 and PR31700 LCD controller registers
  */
+#include <linux/config.h>
 
 /*
  * Begin platform specific configurations
diff -urN linux-2.4.20-pre6/fs/Makefile linux-2.4.20-pre7/fs/Makefile
--- linux-2.4.20-pre6/fs/Makefile	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/Makefile	Thu Sep 12 20:01:48 2002
@@ -66,6 +66,7 @@
 subdir-$(CONFIG_REISERFS_FS)	+= reiserfs
 subdir-$(CONFIG_DEVPTS_FS)	+= devpts
 subdir-$(CONFIG_SUN_OPENPROMFS)	+= openpromfs
+subdir-$(CONFIG_BEFS_FS)	+= befs
 subdir-$(CONFIG_JFS_FS)		+= jfs
 
 
diff -urN linux-2.4.20-pre6/fs/buffer.c linux-2.4.20-pre7/fs/buffer.c
--- linux-2.4.20-pre6/fs/buffer.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/buffer.c	Thu Sep 12 20:01:48 2002
@@ -731,7 +731,7 @@
 {
 	balance_dirty();
 	wakeup_bdflush();
-	try_to_free_pages_nozone(GFP_NOIO);
+	try_to_free_pages(GFP_NOIO);
 	run_task_queue(&tq_disk);
 	yield();
 }
diff -urN linux-2.4.20-pre6/fs/jfs/xattr.c linux-2.4.20-pre7/fs/jfs/xattr.c
--- linux-2.4.20-pre6/fs/jfs/xattr.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/jfs/xattr.c	Thu Sep 12 20:01:49 2002
@@ -577,6 +577,21 @@
 	return rc;
 }
 
+static int can_set_xattr(struct inode *inode, const char *name)
+{
+	if (IS_RDONLY(inode))
+		return -EROFS;
+
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
+		return -EPERM;
+
+	if (!S_ISREG(inode->i_mode) &&
+	    (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
+		return -EPERM;
+
+	return permission(inode, MAY_WRITE);
+}
+
 int __jfs_setxattr(struct inode *inode, const char *name, void *value,
 		   size_t value_len, int flags)
 {
@@ -588,9 +603,12 @@
 	int new_size;
 	int namelen = strlen(name);
 	int found = 0;
-	int rc = 0;
+	int rc;
 	int length;
 
+	if ((rc = can_set_xattr(inode, name)))
+		return rc;
+
 	xattr_size = ea_get(inode, &ea_buf, 0);
 	if (xattr_size < 0) {
 		rc = xattr_size;
@@ -710,6 +728,11 @@
 	return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags);
 }
 
+static int can_get_xattr(struct inode *inode, const char *name)
+{
+	return permission(inode, MAY_READ);
+}
+
 ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
 		       size_t buf_size)
 {
@@ -719,8 +742,12 @@
 	int xattr_size;
 	ssize_t size;
 	int namelen = strlen(name);
+	int rc;
 	char *value;
 
+	if ((rc = can_get_xattr(inode, name)))
+		return rc;
+
 	xattr_size = ea_get(inode, &ea_buf, 0);
 	if (xattr_size < 0) {
 		size = xattr_size;
diff -urN linux-2.4.20-pre6/fs/reiserfs/bitmap.c linux-2.4.20-pre7/fs/reiserfs/bitmap.c
--- linux-2.4.20-pre6/fs/reiserfs/bitmap.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/reiserfs/bitmap.c	Thu Sep 12 20:01:49 2002
@@ -738,7 +738,7 @@
     int rest = amount_needed;
     int nr_allocated;
 
-    while (rest > 0 && start <= finish) {
+    while (rest > 0) {
 	nr_allocated = scan_bitmap (hint->th, &start, finish, 1,
 				    rest + prealloc_size, !hint->formatted_node,
 				    hint->block);
@@ -884,9 +884,7 @@
     if ( !blocks )
 	return;
 
-    spin_lock(&sb->u.reiserfs_sb.bitmap_lock);
     sb->u.reiserfs_sb.reserved_blocks += blocks;
-    spin_unlock(&sb->u.reiserfs_sb.bitmap_lock);
 }
 
 /* Unreserve @blocks amount of blocks in fs pointed by @sb */
@@ -903,22 +901,6 @@
     if ( !blocks )
 	return;
 
-    spin_lock(&sb->u.reiserfs_sb.bitmap_lock);
     sb->u.reiserfs_sb.reserved_blocks -= blocks;
     RFALSE( sb->u.reiserfs_sb.reserved_blocks < 0, "amount of blocks reserved became zero?");
-    spin_unlock(&sb->u.reiserfs_sb.bitmap_lock);
-}
-
-/* This function estimates how much pages we will be able to write to FS
-   used for reiserfs_file_write() purposes for now. */
-int reiserfs_can_fit_pages ( struct super_block *sb /* superblock of filesystem
-						       to estimate space */ )
-{
-	unsigned long space;
-
-	spin_lock(&sb->u.reiserfs_sb.bitmap_lock);
-	space = (SB_FREE_BLOCKS(sb) - sb->u.reiserfs_sb.reserved_blocks) / ( PAGE_CACHE_SIZE/sb->s_blocksize);
-	spin_unlock(&sb->u.reiserfs_sb.bitmap_lock);
-
-	return space;
 }
diff -urN linux-2.4.20-pre6/fs/reiserfs/do_balan.c linux-2.4.20-pre7/fs/reiserfs/do_balan.c
--- linux-2.4.20-pre6/fs/reiserfs/do_balan.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/reiserfs/do_balan.c	Thu Sep 12 20:01:49 2002
@@ -304,6 +304,8 @@
 		    int new_item_len;
 		    int version;
 
+		    RFALSE (!is_direct_le_ih (ih),
+			    "PAP-12075: only direct inserted item can be broken. %h", ih);
 		    ret_val = leaf_shift_left (tb, tb->lnum[0]-1, -1);
 
 		    /* Calculate item length to insert to S[0] */
@@ -326,7 +328,7 @@
 		    version = ih_version (ih);
 
 		    /* Calculate key component, item length and body to insert into S[0] */
-                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + tb->lbytes * (is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize/UNFM_P_SIZE:1) );
+                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + tb->lbytes );
 
 		    put_ih_item_len( ih, new_item_len );
 		    if ( tb->lbytes >  zeros_num ) {
@@ -435,28 +437,23 @@
 				ih_item_len( B_N_PITEM_HEAD(tb->L[0],n+item_pos-ret_val)),
 				l_n,body, zeros_num > l_n ? l_n : zeros_num
 				);
+
+			    RFALSE( l_n && 
+				    is_indirect_le_ih(B_N_PITEM_HEAD
+						      (tb->L[0],
+						       n + item_pos - ret_val)),
+				    "PAP-12110: pasting more than 1 unformatted node pointer into indirect item");
+
 			    /* 0-th item in S0 can be only of DIRECT type when l_n != 0*/
 			    {
-				int version;
-				int temp_l = l_n;
-				
-				RFALSE (ih_item_len (B_N_PITEM_HEAD (tbS0, 0)),
-					"PAP-12106: item length must be 0");
-				RFALSE (comp_short_le_keys (B_N_PKEY (tbS0, 0),
-							    B_N_PKEY (tb->L[0],
-									    n + item_pos - ret_val)),
-					"PAP-12107: items must be of the same file");
-				if (is_indirect_le_ih(B_N_PITEM_HEAD (tb->L[0],
-								      n + item_pos - ret_val)))	{
-				    temp_l = (l_n / UNFM_P_SIZE) * tb->tb_sb->s_blocksize;
-				}
-				/* update key of first item in S0 */
-				version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
-				set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
-						     le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + temp_l);
-				/* update left delimiting key */
-				set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
-						     le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + temp_l);
+			      int version;
+
+			      version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
+			      set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
+						   le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + l_n);
+			      version = ih_version (B_N_PITEM_HEAD(tb->CFL[0],tb->lkey[0]));
+			      set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
+						   le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + l_n);
 			    }
 
 			    /* Calculate new body, position in item and insert_size[0] */
@@ -525,7 +522,7 @@
 			    );
 		    /* if appended item is indirect item, put unformatted node into un list */
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, 0);
+			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
 		    tb->insert_size[0] = 0;
 		    zeros_num = 0;
 		}
@@ -553,11 +550,15 @@
 	    { /* new item or its part falls to R[0] */
 		if ( item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1 )
 		{ /* part of new item falls into R[0] */
-		    loff_t old_key_comp, old_len, r_zeros_number;
+		    int old_key_comp, old_len, r_zeros_number;
 		    const char * r_body;
 		    int version;
 		    loff_t offset;
 
+		    RFALSE( !is_direct_le_ih (ih),
+			    "PAP-12135: only direct item can be split. (%h)", 
+			    ih);
+
 		    leaf_shift_right(tb,tb->rnum[0]-1,-1);
 
 		    version = ih_version(ih);
@@ -566,7 +567,7 @@
 		    old_len = ih_item_len(ih);
 
 		    /* Calculate key component and item length to insert into R[0] */
-                    offset = le_ih_k_offset( ih ) + (old_len - tb->rbytes )*(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize/UNFM_P_SIZE:1);
+                    offset = le_ih_k_offset( ih ) + (old_len - tb->rbytes );
                     set_le_ih_k_offset( ih, offset );
 		    put_ih_item_len( ih, tb->rbytes);
 		    /* Insert part of the item into R[0] */
@@ -574,13 +575,13 @@
 		    bi.bi_bh = tb->R[0];
 		    bi.bi_parent = tb->FR[0];
 		    bi.bi_position = get_right_neighbor_position (tb, 0);
-		    if ( (old_len - tb->rbytes) > zeros_num ) {
+		    if ( offset - old_key_comp > zeros_num ) {
 			r_zeros_number = 0;
-			r_body = body + (old_len - tb->rbytes) - zeros_num;
+			r_body = body + offset - old_key_comp - zeros_num;
 		    }
 		    else {
 			r_body = body;
-			r_zeros_number = zeros_num - (old_len - tb->rbytes);
+			r_zeros_number = zeros_num - (offset - old_key_comp);
 			zeros_num -= r_zeros_number;
 		    }
 
@@ -691,17 +692,12 @@
 			
 			{
 			  int version;
-			  unsigned long temp_rem = n_rem;
 			  
 			  version = ih_version (B_N_PITEM_HEAD (tb->R[0],0));
-			  if (is_indirect_le_key(version,B_N_PKEY(tb->R[0],0))){
-			      temp_rem = (n_rem / UNFM_P_SIZE) * 
-			                 tb->tb_sb->s_blocksize;
-			  }
 			  set_le_key_k_offset (version, B_N_PKEY(tb->R[0],0), 
-					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + temp_rem);
+					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + n_rem);
 			  set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0]), 
-					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + temp_rem);
+					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + n_rem);
 			}
 /*		  k_offset (B_N_PKEY(tb->R[0],0)) += n_rem;
 		  k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/
@@ -725,12 +721,13 @@
 			leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem, r_body, r_zeros_number);
 
 			if (is_indirect_le_ih (B_N_PITEM_HEAD(tb->R[0],0))) {
-#if 0
+
 			    RFALSE( n_rem,
 				    "PAP-12160: paste more than one unformatted node pointer");
-#endif
-			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), 0);
+
+			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), ((struct unfm_nodeinfo*)body)->unfm_freespace);
 			}
+
 			tb->insert_size[0] = n_rem;
 			if ( ! n_rem )
 			    pos_in_item ++;
@@ -769,7 +766,7 @@
 		    }
 
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, 0);
+			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
 		    zeros_num = tb->insert_size[0] = 0;
 		}
 	    }
@@ -846,6 +843,12 @@
 		    const char * r_body;
 		    int version;
 
+		    RFALSE( !is_direct_le_ih(ih),
+			/* The items which can be inserted are:
+			   Stat_data item, direct item, indirect item and directory item which consist of only two entries "." and "..".
+			   These items must not be broken except for a direct one. */
+			    "PAP-12205: non-direct item can not be broken when inserting");
+
 		    /* Move snum[i]-1 items from S[0] to S_new[i] */
 		    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, -1, S_new[i]);
 		    /* Remember key component and item length */
@@ -855,7 +858,7 @@
 
 		    /* Calculate key component and item length to insert into S_new[i] */
                     set_le_ih_k_offset( ih,
-                                le_ih_k_offset(ih) + (old_len - sbytes[i] )*(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize/UNFM_P_SIZE:1) );
+                                le_ih_k_offset(ih) + (old_len - sbytes[i] ) );
 
 		    put_ih_item_len( ih, sbytes[i] );
 
@@ -865,13 +868,13 @@
 		    bi.bi_parent = 0;
 		    bi.bi_position = 0;
 
-		    if ( (old_len - sbytes[i]) > zeros_num ) {
+		    if ( le_ih_k_offset (ih) - old_key_comp > zeros_num ) {
 			r_zeros_number = 0;
-			r_body = body + (old_len - sbytes[i]) - zeros_num;
+			r_body = body + (le_ih_k_offset(ih) - old_key_comp) - zeros_num;
 		    }
 		    else {
 			r_body = body;
-			r_zeros_number = zeros_num - (old_len - sbytes[i]);
+			r_zeros_number = zeros_num - (le_ih_k_offset (ih) - old_key_comp);
 			zeros_num -= r_zeros_number;
 		    }
 
@@ -992,14 +995,11 @@
 
 			    tmp = B_N_PITEM_HEAD(S_new[i],0);
 			    if (is_indirect_le_ih (tmp)) {
-				set_ih_free_space (tmp, 0);
-				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
-					            (n_rem / UNFM_P_SIZE) *
-						    tb->tb_sb->s_blocksize);
-			    } else {
-				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
-				                    n_rem );
+				if (n_rem)
+				    reiserfs_panic (tb->tb_sb, "PAP-12230: balance_leaf: invalid action with indirect item");
+				set_ih_free_space (tmp, ((struct unfm_nodeinfo*)body)->unfm_freespace);
 			    }
+                            set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + n_rem );
 			}
 
 			tb->insert_size[0] = n_rem;
@@ -1045,7 +1045,7 @@
 
 		    /* if we paste to indirect item update ih_free_space */
 		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, 0);
+			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
 		    zeros_num = tb->insert_size[0] = 0;
 		}
 	    }
@@ -1141,12 +1141,11 @@
 		    leaf_paste_in_buffer (&bi, item_pos, pos_in_item, tb->insert_size[0], body, zeros_num);
 
 		    if (is_indirect_le_ih (pasted)) {
-#if 0
+
 			RFALSE( tb->insert_size[0] != UNFM_P_SIZE,
 				"PAP-12280: insert_size for indirect item must be %d, not %d",
 				UNFM_P_SIZE, tb->insert_size[0]);
-#endif
-			set_ih_free_space (pasted, 0);
+			set_ih_free_space (pasted, ((struct unfm_nodeinfo*)body)->unfm_freespace);
 		    }
 		    tb->insert_size[0] = 0;
 		}
diff -urN linux-2.4.20-pre6/fs/reiserfs/file.c linux-2.4.20-pre7/fs/reiserfs/file.c
--- linux-2.4.20-pre6/fs/reiserfs/file.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/reiserfs/file.c	Thu Sep 12 20:01:49 2002
@@ -6,9 +6,6 @@
 #include <linux/sched.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
-#include <asm/uaccess.h>
-#include <linux/pagemap.h>
-#include <linux/locks.h>
 
 /*
 ** We pack the tails of files on file close, not at the time they are written.
@@ -132,1080 +129,9 @@
     return error ;
 }
 
-/* this function from inode.c would be used here, too */
-extern void restart_transaction(struct reiserfs_transaction_handle *th,
-                                struct inode *inode, struct path *path);
-
-/* I really do not want to play with memory shortage right now, so
-   to simplify the code, we are not going to write more than this much pages at
-   a time. This still should considerably improve performance compared to 4k
-   at a time case. */
-#define REISERFS_WRITE_PAGES_AT_A_TIME 32
-
-/* Allocates blocks for a file to fulfil write request.
-   Maps all unmapped but prepared pages from the list.
-   Updates metadata with newly allocated blocknumbers as needed */
-int reiserfs_allocate_blocks_for_region(
-				struct inode *inode, /* Inode we work with */
-				loff_t pos, /* Writing position */
-				int num_pages, /* number of pages write going
-						  to touch */
-				int write_bytes, /* amount of bytes to write */
-				struct page **prepared_pages, /* array of
-							         prepared pages
-							       */
-				int blocks_to_allocate /* Amount of blocks we
-							  need to allocate to
-							  fit the data into file
-							 */
-				)
-{
-    struct cpu_key key; // cpu key of item that we are going to deal with
-    struct item_head *ih; // pointer to item head that we are going to deal with
-    struct buffer_head *bh; // Buffer head that contains items that we are going to deal with
-    struct reiserfs_transaction_handle th; // transaction handle for transaction we are going to create.
-    __u32 * item; // pointer to item we are going to deal with
-    INITIALIZE_PATH(path); // path to item, that we are going to deal with.
-    b_blocknr_t allocated_blocks[blocks_to_allocate]; // Pointer to a place where allocated blocknumbers would be stored. Right now statically allocated, later that will change.
-    reiserfs_blocknr_hint_t hint; // hint structure for block allocator.
-    size_t res; // return value of various functions that we call.
-    int curr_block; // current block used to keep track of unmapped blocks.
-    int i; // loop counter
-    int itempos; // position in item
-    unsigned int from = (pos & (PAGE_CACHE_SIZE - 1)); // writing position in
-						       // first page
-    unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1; /* last modified byte offset in last page */
-    __u64 hole_size ; // amount of blocks for a file hole, if it needed to be created.
-    int modifying_this_item = 0; // Flag for items traversal code to keep track
-				 // of the fact that we already prepared
-				 // current block for journal
-
-
-    RFALSE(!blocks_to_allocate, "green-9004: tried to allocate zero blocks?");
-
-    /* First we compose a key to point at the writing position, we want to do
-       that outside of any locking region. */
-    make_cpu_key (&key, inode, pos+1, TYPE_ANY, 3/*key length*/);
-
-    /* If we came here, it means we absolutely need to open a transaction,
-       since we need to allocate some blocks */
-    lock_kernel(); // Journaling stuff and we need that.
-    journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1); // Wish I know if this number enough
-    reiserfs_update_inode_transaction(inode) ;
-
-    /* Look for the in-tree position of our write, need path for block allocator */
-    res = search_for_position_by_key(inode->i_sb, &key, &path);
-    if ( res == IO_ERROR ) {
-	res = -EIO;
-	goto error_exit;
-    }
-   
-    /* Allocate blocks */
-    /* First fill in "hint" structure for block allocator */
-    hint.th = &th; // transaction handle.
-    hint.path = &path; // Path, so that block allocator can determine packing locality or whatever it needs to determine.
-    hint.inode = inode; // Inode is needed by block allocator too.
-    hint.search_start = 0; // We have no hint on where to search free blocks for block allocator.
-    hint.key = key.on_disk_key; // on disk key of file.
-    hint.block = inode->i_blocks/(inode->i_sb->s_blocksize/512); // Number of disk blocks this file occupies already.
-    hint.formatted_node = 0; // We are allocating blocks for unformatted node.
-    hint.preallocate = 0; // We do not do any preallocation for now.
-
-    /* Call block allocator to allocate blocks */
-    res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
-    if ( res != CARRY_ON ) {
-	if ( res == NO_DISK_SPACE ) {
-	    /* We flush the transaction in case of no space. This way some
-	       blocks might become free */
-	    SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
-	    restart_transaction(&th, inode, &path);
-
-	    /* We might have scheduled, so search again */
-	    res = search_for_position_by_key(inode->i_sb, &key, &path);
-	    if ( res == IO_ERROR ) {
-		res = -EIO;
-		goto error_exit;
-	    }
-
-	    /* update changed info for hint structure. */
-	    res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
-	    if ( res != CARRY_ON ) {
-		res = -ENOSPC; 
-		pathrelse(&path);
-		goto error_exit;
-	    }
-	} else {
-	    res = -ENOSPC;
-	    pathrelse(&path);
-	    goto error_exit;
-	}
-    }
-
-#ifdef __BIG_ENDIAN
-        // Too bad, I have not found any way to convert a given region from
-        // cpu format to little endian format
-    {
-        int i;
-        for ( i = 0; i < blocks_to_allocate ; i++)
-            allocated_blocks[i]=cpu_to_le32(allocated_blocks[i]);
-    }
-#endif
-
-    /* Blocks allocating well might have scheduled and tree might have changed,
-       let's search the tree again */
-    /* find where in the tree our write should go */
-    res = search_for_position_by_key(inode->i_sb, &key, &path);
-    if ( res == IO_ERROR ) {
-	res = -EIO;
-	goto error_exit_free_blocks;
-    }
-
-    bh = get_last_bh( &path ); // Get a bufferhead for last element in path.
-    ih = get_ih( &path );      // Get a pointer to last item head in path.
-    item = get_item( &path );  // Get a pointer to last item in path
-
-    /* Let's see what we have found */
-    if ( res != POSITION_FOUND ) { /* position not found, this means that we
-				      might need to append file with holes
-				      first */
-	// Since we are writing past the file's end, we need to find out if
-	// there is a hole that needs to be inserted before our writing
-	// position, and how many blocks it is going to cover (we need to
-	//  populate pointers to file blocks representing the hole with zeros)
-
-	hole_size = (pos + 1 - (le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key))+op_bytes_number(ih, inode->i_sb->s_blocksize))) >> inode->i_sb->s_blocksize_bits;
-
-	if ( hole_size > 0 ) {
-	    int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE ); // How much data to insert first time.
-	    /* area filled with zeroes, to supply as list of zero blocknumbers
-	       We allocate it outside of loop just in case loop would spin for
-	       several iterations. */
-	    char *zeros = kmalloc(to_paste*UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway.
-	    if ( !zeros ) {
-		res = -ENOMEM;
-		goto error_exit_free_blocks;
-	    }
-	    memset ( zeros, 0, to_paste*UNFM_P_SIZE);
-	    do {
-		to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE );
-		if ( is_indirect_le_ih(ih) ) {
-		    /* Ok, there is existing indirect item already. Need to append it */
-		    /* Calculate position past inserted item */
-		    make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
-		    res = reiserfs_paste_into_item( &th, &path, &key, (char *)zeros, UNFM_P_SIZE*to_paste);
-		    if ( res ) {
-			kfree(zeros);
-			goto error_exit_free_blocks;
-		    }
-		} else if ( is_statdata_le_ih(ih) ) {
-		    /* No existing item, create it */
-		    /* item head for new item */
-		    struct item_head ins_ih;
-
-		    /* create a key for our new item */
-		    make_cpu_key( &key, inode, 1, TYPE_INDIRECT, 3);
-
-		    /* Create new item head for our new item */
-		    make_le_item_head (&ins_ih, &key, key.version, 1,
-				       TYPE_INDIRECT, to_paste*UNFM_P_SIZE,
-				       0 /* free space */);
-
-		    /* Find where such item should live in the tree */
-		    res = search_item (inode->i_sb, &key, &path);
-		    if ( res != ITEM_NOT_FOUND ) {
-			/* item should not exist, otherwise we have error */
-			if ( res != -ENOSPC ) {
-			    reiserfs_warning ("green-9008: search_by_key (%K) returned %d\n",
-					       &key, res);
-			}
-			res = -EIO;
-		        kfree(zeros);
-			goto error_exit_free_blocks;
-		    }
-		    res = reiserfs_insert_item( &th, &path, &key, &ins_ih, (char *)zeros);
-		} else {
-		    reiserfs_panic(inode->i_sb, "green-9011: Unexpected key type %K\n", &key);
-		}
-		if ( res ) {
-		    kfree(zeros);
-		    goto error_exit_free_blocks;
-		}
-		/* Now we want to check if transaction is too full, and if it is
-		   we restart it. This will also free the path. */
-		if (journal_transaction_should_end(&th, th.t_blocks_allocated))
-		    restart_transaction(&th, inode, &path);
-
-		/* Well, need to recalculate path and stuff */
-		set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + to_paste * inode->i_sb->s_blocksize );
-		res = search_for_position_by_key(inode->i_sb, &key, &path);
-		if ( res == IO_ERROR ) {
-		    res = -EIO;
-		    kfree(zeros);
-		    goto error_exit_free_blocks;
-		}
-		bh=get_last_bh(&path);
-		ih=get_ih(&path);
-		item = get_item(&path);
-		hole_size -= to_paste;
-	    } while ( hole_size );
-	    kfree(zeros);
-	}
-    }
-
-    // Go through existing indirect items first
-    // replace all zeroes with blocknumbers from list
-    // Note that if no corresponding item was found, by previous search,
-    // it means there are no existing in-tree representation for file area
-    // we are going to overwrite, so there is nothing to scan through for holes.
-    for ( curr_block = 0, itempos = path.pos_in_item ; curr_block < blocks_to_allocate && res == POSITION_FOUND ; ) {
-
-	if ( itempos >= ih_item_len(ih)/UNFM_P_SIZE ) {
-	    /* We run out of data in this indirect item, let's look for another
-	       one. */
-	    /* First if we are already modifying current item, log it */
-	    if ( modifying_this_item ) {
-		journal_mark_dirty (&th, inode->i_sb, bh);
-		modifying_this_item = 0;
-	    }
-	    /* Then set the key to look for a new indirect item (offset of old
-	       item is added to old item length */
-	    set_cpu_key_k_offset( &key, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize));
-	    /* Search ofor position of new key in the tree. */
-	    res = search_for_position_by_key(inode->i_sb, &key, &path);
-	    if ( res == IO_ERROR) {
-		res = -EIO;
-		goto error_exit_free_blocks;
-	    }
-	    bh=get_last_bh(&path);
-	    ih=get_ih(&path);
-	    item = get_item(&path);
-	    itempos = path.pos_in_item;
-	    continue; // loop to check all kinds of conditions and so on.
-	}
-	/* Ok, we have correct position in item now, so let's see if it is
-	   representing file hole (blocknumber is zero) and fill it if needed */
-	if ( !item[itempos] ) {
-	    /* Ok, a hole. Now we need to check if we already prepared this
-	       block to be journaled */
-	    while ( !modifying_this_item ) { // loop until succeed
-		/* Well, this item is not journaled yet, so we must prepare
-		   it for journal first, before we can change it */
-		struct item_head tmp_ih; // We copy item head of found item,
-					 // here to detect if fs changed under
-					 // us while we were preparing for
-					 // journal.
-		int fs_gen; // We store fs generation here to find if someone
-			    // changes fs under our feet
-
-		copy_item_head (&tmp_ih, ih); // Remember itemhead
-		fs_gen = get_generation (inode->i_sb); // remember fs generation
-		reiserfs_prepare_for_journal(inode->i_sb, bh, 1); // Prepare a buffer within which indirect item is stored for changing.
-		if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-		    // Sigh, fs was changed under us, we need to look for new
-		    // location of item we are working with
-
-		    /* unmark prepaerd area as journaled and search for it's
-		       new position */
-		    reiserfs_restore_prepared_buffer(inode->i_sb, bh);
-		    res = search_for_position_by_key(inode->i_sb, &key, &path);
-		    if ( res == IO_ERROR) {
-			res = -EIO;
-			goto error_exit_free_blocks;
-		    }
-		    bh=get_last_bh(&path);
-		    ih=get_ih(&path);
-		    item = get_item(&path);
-		    // Itempos is still the same
-		    continue;
-		}
-		modifying_this_item = 1;
-	    }
-	    item[itempos] = allocated_blocks[curr_block]; // Assign new block
-	    curr_block++;
-	}
-	itempos++;
-    }
-
-    if ( modifying_this_item ) { // We need to log last-accessed block, if it
-				 // was modified, but not logged yet.
-	journal_mark_dirty (&th, inode->i_sb, bh);
-    }
-
-    if ( curr_block < blocks_to_allocate ) {
-	// Oh, well need to append to indirect item, or to create indirect item
-	// if there weren't any
-	if ( is_indirect_le_ih(ih) ) {
-	    // Existing indirect item - append. First calculate key for append
-	    // position. We do not need to recalculate path as it should
-	    // already point to correct place.
-	    make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
-	    res = reiserfs_paste_into_item( &th, &path, &key, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block));
-	    if ( res ) {
-		goto error_exit_free_blocks;
-	    }
-	} else if (is_statdata_le_ih(ih) ) {
-	    // Last found item was statdata. That means we need to create indirect item.
-	    struct item_head ins_ih; /* itemhead for new item */
-
-	    /* create a key for our new item */
-	    make_cpu_key( &key, inode, 1, TYPE_INDIRECT, 3); // Position one,
-							    // because that's
-							    // where first
-							    // indirect item
-							    // begins
-	    /* Create new item head for our new item */
-	    make_le_item_head (&ins_ih, &key, key.version, 1, TYPE_INDIRECT,
-			       (blocks_to_allocate-curr_block)*UNFM_P_SIZE,
-			       0 /* free space */);
-	    /* Find where such item should live in the tree */
-	    res = search_item (inode->i_sb, &key, &path);
-	    if ( res != ITEM_NOT_FOUND ) {
-		/* Well, if we have found such item already, or some error
-		   occured, we need to warn user and return error */
-		if ( res != -ENOSPC ) {
-		    reiserfs_warning ("green-9009: search_by_key (%K) returned %d\n",
-			              &key, res);
-		}
-		res = -EIO;
-		goto error_exit_free_blocks;
-	    }
-	    /* Insert item into the tree with the data as its body */
-	    res = reiserfs_insert_item( &th, &path, &key, &ins_ih, (char *)(allocated_blocks+curr_block));
-	} else {
-	    reiserfs_panic(inode->i_sb, "green-9010: unexpected item type for key %K\n",&key);
-	}
-    }
-
-    /* Now the final thing, if we have grew the file, we must update it's size*/
-    if ( pos + write_bytes > inode->i_size) {
-	inode->i_size = pos + write_bytes; // Set new size
-    }
-
-    /* Amount of on-disk blocks used by file have changed, update it */
-    inode->i_blocks += blocks_to_allocate * (inode->i_sb->s_blocksize / 512);
-    reiserfs_update_sd(&th, inode); // And update on-disk metadata
-    // finish all journal stuff now, We are not going to play with metadata
-    // anymore.
-    pathrelse(&path);
-    journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1);
-    unlock_kernel();
-
-    // go through all the pages/buffers and map the buffers to newly allocated
-    // blocks (so that system knows where to write these pages later).
-    curr_block = 0;
-    for ( i = 0; i < num_pages ; i++ ) {
-	struct page *page=prepared_pages[i]; //current page
-	struct buffer_head *head = page->buffers; // first buffer for a page
-	int block_start, block_end; // in-page offsets for buffers.
-
-	if (!page->buffers)
-	    reiserfs_panic(inode->i_sb, "green-9005: No buffers for prepared page???");
-
-	/* For each buffer in page */
-	for(bh = head, block_start = 0; bh != head || !block_start;
-	    block_start=block_end, bh = bh->b_this_page) {
-	    if (!bh)
-		reiserfs_panic(inode->i_sb, "green-9006: Allocated but absent buffer for a page?");
-	    block_end = block_start+inode->i_sb->s_blocksize;
-	    if (i == 0 && block_end <= from )
-		/* if this buffer is before requested data to map, skip it */
-		continue;
-	    if (i == num_pages - 1 && block_start >= to)
-		/* If this buffer is after requested data to map, abort
-		   processing of current page */
-		break;
-
-	    if ( !buffer_mapped(bh) ) { // Ok, unmapped buffer, need to map it
-		bh->b_dev = inode->i_dev;
-		bh->b_blocknr = le32_to_cpu(allocated_blocks[curr_block]);
-		set_bit(BH_Mapped, &bh->b_state);
-		curr_block++;
-	    }
-	}
-    }
-
-    RFALSE( curr_block > blocks_to_allocate, "green-9007: Used too many blocks? weird");
-
-    return 0;
-
-// Need to deal with transaction here.
-error_exit_free_blocks:
-    pathrelse(&path);
-    // free blocks
-    for( i = 0; i < blocks_to_allocate; i++ )
-	reiserfs_free_block( &th, le32_to_cpu(allocated_blocks[i]));
-
-error_exit:
-    journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1);
-    unlock_kernel();
-
-    return res;
-}
-
-/* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
-void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */
-			      int num_pages /* amount of pages */) {
-    int i; // loop counter
-
-    for (i=0; i < num_pages ; i++) {
-	struct page *page = prepared_pages[i];
-
-	try_to_free_buffers(page,0);
-	kunmap(page);
-	UnlockPage(page);
-	page_cache_release(page);
-    }
-}
-
-/* This function will copy data from userspace to specified pages within
-   supplied byte range */
-int reiserfs_copy_from_user_to_file_region(
-				loff_t pos, /* In-file position */
-				int num_pages, /* Number of pages affected */
-				int write_bytes, /* Amount of bytes to write */
-				struct page **prepared_pages, /* pointer to 
-								 array to
-								 prepared pages
-								*/
-				const char *buf /* Pointer to user-supplied
-						   data*/
-				)
-{
-    long page_fault=0; // status of copy_from_user.
-    int i; // loop counter.
-    int offset; // offset in page
-
-    for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) {
-	int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page
-	struct page *page=prepared_pages[i]; // Current page we process.
-
-	/* Bring in the user page. We need to do it to fight some deadlocks
-	   with copying the page to itself and page being inaccessible at
-	   the same time.*/
-	{ volatile unsigned char dummy;
-	    __get_user(dummy, buf);
-	    __get_user(dummy, buf+count-1);
-	    /* We do getuser for beginning and ending of the region just because
-	       userdata may be not page aligned, and therefore data that will
-	       go into one page of file may be splitted onto two actual pages
-	       in userspace */
-	}
-
-	/* Copy data from userspace to the current page */
-	page_fault = __copy_from_user(page_address(page)+offset, buf, count); // Copy the data.
-	/* Flush processor's dcache for this page */
-	flush_dcache_page(page);
-	buf+=count;
-	write_bytes-=count;
-
-	if (page_fault)
-	    break; // Was there a fault? abort.
-    }
-
-    return page_fault?-EFAULT:0;
-}
-
-
-
-/* Submit pages for write. This was separated from actual file copying
-   because we might want to allocate block numbers in-between.
-   This function assumes that caller will adjust file size to correct value. */
-int reiserfs_submit_file_region_for_write(
-				loff_t pos, /* Writing position offset */
-				int num_pages, /* Number of pages to write */
-				int write_bytes, /* number of bytes to write */
-				struct page **prepared_pages /* list of pages */
-				)
-{
-    int status; // return status of block_commit_write.
-    int retval = 0; // Return value we are going to return.
-    int i; // loop counter
-    int offset; // Writing offset in page.
-
-    for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) {
-	int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page
-	struct page *page=prepared_pages[i]; // Current page we process.
-
-	status = block_commit_write(page, offset, offset+count); // Note this also kunmaps kmapped page.
-	if ( status )
-	    retval = status; // To not overcomplicate matters We are going to
-			     // submit all the pages even if there was error.
-			     // we only remember error status to report it on
-			     // exit.
-	write_bytes-=count;
-	SetPageReferenced(page);
-	UnlockPage(page); // We unlock the page as it was locked by earlier call
-			  // to grab_cache_page
-	page_cache_release(page);
-    }
-    return retval;
-}
-
-/* Look if passed writing region is going to touch file's tail
-   (if it is present). And if it is, convert the tail to unformatted node */
-int reiserfs_check_for_tail_and_convert( struct inode *inode, /* inode to deal with */
-					 loff_t pos, /* Writing position */
-					 int write_bytes /* amount of bytes to write */
-				        )
-{
-    INITIALIZE_PATH(path); // needed for search_for_position
-    struct cpu_key key; // Key that would represent last touched writing byte.
-    struct item_head *ih; // item header of found block;
-    int res; // Return value of various functions we call.
-    int cont_expand_offset; // We will put offset for generic_cont_expand here
-			    // This can be int just because tails are created
-			    // only for small files.
- 
-/* this embodies a dependency on a particular tail policy */
-    if ( inode->i_size >= inode->i_sb->s_blocksize*4 ) {
-	/* such a big files do not have tails, so we won't bother ourselves
-	   to look for tails, simply return */
-	return 0;
-    }
-
-    lock_kernel();
-    /* find the item containing the last byte to be written, or if
-     * writing past the end of the file then the last item of the
-     * file (and then we check its type). */
-    make_cpu_key (&key, inode, pos+write_bytes+1, TYPE_ANY, 3/*key length*/);
-    res = search_for_position_by_key(inode->i_sb, &key, &path);
-    if ( res == IO_ERROR ) {
-        unlock_kernel();
-	return -EIO;
-    }
-    ih = get_ih(&path);
-    res = 0;
-    if ( is_direct_le_ih(ih) ) {
-	/* Ok, closest item is file tail (tails are stored in "direct"
-	 * items), so we need to unpack it. */
-	/* To not overcomplicate matters, we just call generic_cont_expand
-	   which will in turn call other stuff and finally will boil down to
-	    reiserfs_get_block() that would do necessary conversion. */
-	cont_expand_offset = le_key_k_offset(get_inode_item_key_version(inode), &(ih->ih_key));
-	pathrelse(&path);
-	res = generic_cont_expand( inode, cont_expand_offset);
-    } else
-	pathrelse(&path);
-
-    unlock_kernel();
-    return res;
-}
-
-/* This functions kmaps and locks pages starting from @pos for @inode.
-   @num_pages pages are locked and stored in
-   @prepared_pages array. Also buffers are allocated for these pages.
-   First and last page of the region is read if it is overwritten only
-   partially. If last page did not exist before write (file hole or file
-   append), it is zeroed, then. 
-   Returns number of unallocated blocks that should be allocated to cover
-   new file data.*/
-int reiserfs_prepare_file_region_for_write(
-				struct inode *inode /* Inode of the file */,
-				loff_t pos, /* position in the file */
-				int num_pages, /* number of pages to
-					          prepare */
-				int write_bytes, /* Amount of bytes to be
-						    overwritten from
-						    @pos */
-				struct page **prepared_pages /* pointer to array
-							       where to store
-							       prepared pages */
-					   )
-{
-    int res=0; // Return values of different functions we call.
-    unsigned long index = pos >> PAGE_CACHE_SHIFT; // Offset in file in pages.
-    int from = (pos & (PAGE_CACHE_SIZE - 1)); // Writing offset in first page
-    int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
-					 /* offset of last modified byte in last
-				            page */
-    struct address_space *mapping = inode->i_mapping; // Pages are mapped here.
-    int i; // Simple counter
-    int blocks = 0; /* Return value (blocks that should be allocated) */
-    struct buffer_head *bh, *head; // Current bufferhead and first bufferhead
-				   // of a page.
-    unsigned block_start, block_end; // Starting and ending offsets of current
-				     // buffer in the page.
-    struct buffer_head *wait[2], **wait_bh=wait; // Buffers for page, if
-						 // Page appeared to be not up
-						 // to date. Note how we have
-						 // at most 2 buffers, this is
-						 // because we at most may
-						 // partially overwrite two
-						 // buffers for one page. One at                                                 // the beginning of write area
-						 // and one at the end.
-						 // Everything inthe middle gets                                                 // overwritten totally.
-
-    struct cpu_key key; // cpu key of item that we are going to deal with
-    struct item_head *ih = NULL; // pointer to item head that we are going to deal with
-    struct buffer_head *itembuf=NULL; // Buffer head that contains items that we are going to deal with
-    INITIALIZE_PATH(path); // path to item, that we are going to deal with.
-    __u32 * item=0; // pointer to item we are going to deal with
-
-
-    if ( num_pages < 1 ) {
-	reiserfs_warning("green-9001: reiserfs_prepare_file_region_for_write called with zero number of pages to process\n");
-	return -EFAULT;
-    }
-
-    /* We have 2 loops for pages. In first loop we grab and lock the pages, so
-       that nobody would touch these until we release the pages. Then
-       we'd start to deal with mapping buffers to blocks. */
-    for ( i = 0; i < num_pages; i++) {
-	prepared_pages[i] = grab_cache_page(mapping, index + i); // locks the page
-	if ( !prepared_pages[i]) {
-	    res = -ENOMEM;
-	    goto failed_page_grabbing;
-	}
-	kmap(prepared_pages[i]); // MAp the page in conventional RAM.
-	if (!prepared_pages[i]->buffers)
-	    create_empty_buffers(prepared_pages[i], inode->i_dev, inode->i_sb->s_blocksize);
-    }
-
-    /* Let's count amount of blocks for a case where all the blocks
-       overwritten are new (we will substract already allocated blocks later)*/
-    if ( num_pages > 2 )
-	/* These are full-overwritten pages so we count all the blocks in
-	   these pages are counted as needed to be allocated */
-	blocks = (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize) * (num_pages - 2);
-
-    /* count blocks needed for first page (possibly partially written) */
-    blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_sb->s_blocksize_bits) +
-	   !!(from & (inode->i_sb->s_blocksize-1)); /* roundup */
-
-    /* Now we account for last page. If last page == first page (we
-       overwrite only one page), we substract all the blocks past the
-       last writing position in a page out of already calculated number
-       of blocks */
-    blocks += (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize) * (num_pages > 1) -
-	   ((PAGE_CACHE_SIZE - to) >> inode->i_sb->s_blocksize_bits);
-	   /* Note how we do not roundup here since partial blocks still
-		   should be allocated */
-
-    /* Now if all the write area lies past the file end, no point in
-       maping blocks, since there is none, so we just zero out remaining
-       parts of first and last pages in write area (if needed) */
-    if ( (pos & ~(PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
-	if ( from != 0 ) {/* First page needs to be partially zeroed */
-	    memset(page_address(prepared_pages[0]), 0, from);
-	    SetPageUptodate(prepared_pages[0]);
-	}
-	if ( to != PAGE_CACHE_SIZE ) { /* Last page needs to be partially zeroed */
-	    memset(page_address(prepared_pages[num_pages-1])+to, 0, PAGE_CACHE_SIZE - to);
-	    SetPageUptodate(prepared_pages[num_pages-1]);
-	}
-
-	/* Since all blocks are new - use already calculated value */
-	return blocks;
-    }
-
-    /* Well, since we write somewhere into the middle of a file, there is
-       possibility we are writing over some already allocated blocks, so
-       let's map these blocks and substract number of such blocks out of blocks
-       we need to allocate (calculated above) */
-    /* Mask write position to start on blocksize, we do it out of the
-       loop for performance reasons */
-    pos &= ~(inode->i_sb->s_blocksize - 1);
-    /* Set cpu key to the starting position in a file (on left block boundary)*/
-    make_cpu_key (&key, inode, 1 + ((pos) & ~(inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
-
-    lock_kernel(); // We need that for at least search_by_key()
-    for ( i = 0; i < num_pages ; i++ ) { 
-	int item_pos=-1; /* Position in indirect item */
-
-	head = prepared_pages[i]->buffers;
-	/* For each buffer in the page */
-	for(bh = head, block_start = 0; bh != head || !block_start;
-	    block_start=block_end, bh = bh->b_this_page) {
-		if (!bh)
-		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
-		/* Find where this buffer ends */
-		block_end = block_start+inode->i_sb->s_blocksize;
-		if (i == 0 && block_end <= from )
-		    /* if this buffer is before requested data to map, skip it*/
-		    continue;
-
-		if (i == num_pages - 1 && block_start >= to) {
-		    /* If this buffer is after requested data to map, abort
-		       processing of current page */
-		    break;
-		}
-
-		if ( buffer_mapped(bh) && bh->b_blocknr !=0 ) {
-		    /* This is optimisation for a case where buffer is mapped
-		       and have blocknumber assigned. In case significant amount
-		       of such buffers are present, we may avoid some amount
-		       of search_by_key calls.
-		       Probably it would be possible to move parts of this code
-		       out of BKL, but I afraid that would overcomplicate code
-		       without any noticeable benefit.
-		    */
-		    item_pos++;
-		    /* Update the key */
-		    set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + inode->i_sb->s_blocksize);
-		    blocks--; // Decrease the amount of blocks that need to be
-			      // allocated
-		    continue; // Go to the next buffer
-		}
-
-		if ( !itembuf || /* if first iteration */
-		     item_pos >= ih_item_len(ih)/UNFM_P_SIZE)
-					     { /* or if we progressed past the
-						  current unformatted_item */
-			/* Try to find next item */
-			res = search_for_position_by_key(inode->i_sb, &key, &path);
-			/* Abort if no more items */
-			if ( res != POSITION_FOUND )
-			    break;
-
-			/* Update information about current indirect item */
-			itembuf = get_last_bh( &path );
-			ih = get_ih( &path );
-			item = get_item( &path );
-			item_pos = path.pos_in_item;
-
-			RFALSE( !is_indirect_le_ih (ih), "green-9003: indirect item expected");
-		}
-
-		/* See if there is some block associated with the file
-		   at that position, map the buffer to this block */
-		if ( get_block_num(item,item_pos) ) {
-		    bh->b_dev = inode->i_dev;
-		    bh->b_blocknr = get_block_num(item,item_pos);
-		    set_bit(BH_Mapped, &bh->b_state);
-		    blocks--; // Decrease the amount of blocks that need to be
-			      // allocated
-		}
-		item_pos++;
-		/* Update the key */
-		set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + inode->i_sb->s_blocksize);
-	}
-    }
-    pathrelse(&path); // Free the path
-    unlock_kernel();
-
-	/* Now zero out unmappend buffers for the first and last pages of
-	   write area or issue read requests if page is mapped. */
-	/* First page, see if it is not uptodate */
-	if ( !Page_Uptodate(prepared_pages[0]) ) {
-	    head = prepared_pages[0]->buffers;
-
-	    /* For wach buffer in page */
-	    for(bh = head, block_start = 0; bh != head || !block_start;
-		block_start=block_end, bh = bh->b_this_page) {
-
-		if (!bh)
-		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
-		/* Find where this buffer ends */
-		block_end = block_start+inode->i_sb->s_blocksize;
-		if ( block_end <= from )
-		    /* if this buffer is before requested data to map, skip it*/
-		    continue;
-		if ( block_start < from ) { /* Aha, our partial buffer */
-		    if ( buffer_mapped(bh) ) { /* If it is mapped, we need to
-						  issue READ request for it to
-						  not loose data */
-			ll_rw_block(READ, 1, &bh);
-			*wait_bh++=bh;
-		    } else { /* Not mapped, zero it */
-			memset(page_address(prepared_pages[0])+block_start, 0, from-block_start);
-			set_bit(BH_Uptodate, &bh->b_state);
-		    }
-		}
-	    }
-	}
-
-	/* Last page, see if it is not uptodate, or if the last page is past the end of the file. */
-	if ( !Page_Uptodate(prepared_pages[num_pages-1]) || 
-	    ((pos+write_bytes)>>PAGE_CACHE_SHIFT) > (inode->i_size>>PAGE_CACHE_SHIFT) ) {
-	    head = prepared_pages[num_pages-1]->buffers;
-
-	    /* for each buffer in page */
-	    for(bh = head, block_start = 0; bh != head || !block_start;
-		block_start=block_end, bh = bh->b_this_page) {
-
-		if (!bh)
-		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
-		/* Find where this buffer ends */
-		block_end = block_start+inode->i_sb->s_blocksize;
-		if ( block_start >= to )
-		    /* if this buffer is after requested data to map, skip it*/
-		    break;
-		if ( block_end > to ) { /* Aha, our partial buffer */
-		    if ( buffer_mapped(bh) ) { /* If it is mapped, we need to
-						  issue READ request for it to
-						  not loose data */
-			ll_rw_block(READ, 1, &bh);
-			*wait_bh++=bh;
-		    } else { /* Not mapped, zero it */
-			memset(page_address(prepared_pages[num_pages-1])+to, 0, block_end-to);
-			set_bit(BH_Uptodate, &bh->b_state);
-		    }
-		}
-	    }
-	}
-
-    /* Wait for read requests we made to happen, if necessary */
-    while(wait_bh > wait) {
-	wait_on_buffer(*--wait_bh);
-	if (!buffer_uptodate(*wait_bh)) {
-	    res = -EIO;
-	    goto failed_read;
-	}
-    }
-
-    return blocks;
-failed_page_grabbing:
-    num_pages = i;
-failed_read:
-    reiserfs_unprepare_pages(prepared_pages, num_pages);
-    return res;
-}
-
-/* Write @count bytes at position @ppos in a file indicated by @file
-   from the buffer @buf.  
-
-   generic_file_write() is only appropriate for filesystems that are not seeking to optimize performance and want
-   something simple that works.  It is not for serious use by general purpose filesystems, excepting the one that it was
-   written for (ext2/3).  This is for several reasons:
-
-   * It has no understanding of any filesystem specific optimizations.
-
-   * It enters the filesystem repeatedly for each page that is written.
-
-   * It depends on reiserfs_get_block() function which if implemented by reiserfs performs costly search_by_key
-   * operation for each page it is supplied with. By contrast reiserfs_file_write() feeds as much as possible at a time
-   * to reiserfs which allows for fewer tree traversals.
-
-   * Each indirect pointer insertion takes a lot of cpu, because it involves memory moves inside of blocks.
-
-   * Asking the block allocation code for blocks one at a time is slightly less efficient.
-
-   All of these reasons for not using only generic file write were understood back when reiserfs was first miscoded to
-   use it, but we were in a hurry to make code freeze, and so it couldn't be revised then.  This new code should make
-   things right finally.
-
-   Future Features: providing search_by_key with hints.
-
-*/
-ssize_t reiserfs_file_write( struct file *file, /* the file we are going to write into */
-                             const char *buf, /*  pointer to user supplied data
-(in userspace) */
-                             size_t count, /* amount of bytes to write */
-                             loff_t *ppos /* pointer to position in file that we start writing at. Should be updated to
-                                           * new current position before returning. */ )
-{
-    size_t already_written = 0; // Number of bytes already written to the file.
-    loff_t pos; // Current position in the file.
-    size_t res; // return value of various functions that we call.
-    unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; // Current filesize limit
-    struct inode *inode = file->f_dentry->d_inode; // Inode of the file that we are writing to.
-    struct page * prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
-				/* To simplify coding at this time, we store
-				   locked pages in array for now */
-    if ( count <= PAGE_CACHE_SIZE || file->f_flags & O_DIRECT)
-        return generic_file_write(file, buf, count, ppos);
-
-    if ( (ssize_t) count < 0 )
-        return -EINVAL;
-
-    if (!access_ok(VERIFY_READ, buf, count))
-        return -EFAULT;
-
-    down(&inode->i_sem); // locks the entire file for just us
-
-    // We are going to duplicate a lot of generic_file_write checks here
-    // for now. I do not have any good idea on how to avoid these now.
-
-    res = -EINVAL;
-    if ( *ppos < 0)
-	goto out;
-
-    res = file->f_error;
-    if ( res ) {
-	file->f_error = 0;
-	goto out;
-    }
-
-    if (file->f_flags & O_APPEND)
-	pos=inode->i_size;
-    else
-	pos=*ppos;
-
-    res = -EFBIG;
-    if ( limit != RLIM_INFINITY) {
-	if (pos >= limit) {
-	    send_sig(SIGXFSZ, current, 0);
-	    goto out;
-	}
-	if ( pos > 0xFFFFFFFFULL || count > limit - (u32)pos) {
-	    count = limit - (u32)pos;
-	}
-    }
-
-    // LFS
-    if ( pos + count > MAX_NON_LFS && !(file->f_flags & O_LARGEFILE) ) {
-	if ( pos >= MAX_NON_LFS ) {
-	    send_sig(SIGXFSZ, current, 0);
-	    goto out;
-	}
-	if ( count > MAX_NON_LFS - (u32)pos ) {
-	    count = MAX_NON_LFS - (u32)pos;
-	}
-    }
-
-    // Check we are not going to exceed block limit
-    if ( pos >= inode->i_sb->s_maxbytes) {
-	if ( count || pos > inode->i_sb->s_maxbytes) {
-	    send_sig(SIGXFSZ, current, 0);
-	    goto out;
-	}
-	// zero length writes are ok.
-    }
-
-    res = 0;
-    if ( count == 0 )
-	goto out;
-
-    remove_suid(inode);
-    /* Mark inode dirty only in case times are actually changed.
-       This is to speed things up */
-    {
-	time_t now = CURRENT_TIME;
-	if (inode->i_ctime != now || inode->i_mtime != now) {
-	    inode->i_ctime = inode->i_mtime = now;
-	    mark_inode_dirty_sync(inode);
-	}
-    }
-
-
-    // Ok, we are done with all the checks.
-
-    // Now we should start real work
-
-    /* If we are going to write past the file's packed tail or if we are going
-       to overwrite part of the tail, we need that tail to be converted into
-       unformatted node */
-    res = reiserfs_check_for_tail_and_convert( inode, pos, count);
-    if (res)
-	goto out;
-
-    while ( count > 0) {
-	/* This is the main loop in which we running until some error occures
-	   or until we write all of the data. */
-	int num_pages;/* amount of pages we are going to write this iteration */
-	int write_bytes; /* amount of bytes to write during this iteration */
-	int blocks_to_allocate; /* how much blocks we need to allocate for
-				   this iteration */
-        
-        /*  (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos*/
-	num_pages = !!((pos+count) & (PAGE_CACHE_SIZE - 1)) + /* round up partial
-							  pages */
-		    ((count + (pos & (PAGE_CACHE_SIZE-1))) >> PAGE_CACHE_SHIFT); 
-						/* convert size to amount of
-						   pages */
-/* all lock_kernels should be changed to lock_supers in reiserfs, but they need to be changed all at once and all together */
-	lock_kernel();
-	if ( num_pages > REISERFS_WRITE_PAGES_AT_A_TIME 
-		|| num_pages > reiserfs_can_fit_pages(inode->i_sb) ) {
-	    /* If we were asked to write more data than we want to or if there
-	       is not that much space, then we shorten amount of data to write
-	       for this iteration. */
-	    num_pages = min_t(int, REISERFS_WRITE_PAGES_AT_A_TIME, reiserfs_can_fit_pages(inode->i_sb));
-	    /* Also we should not forget to set size in bytes accordingly */
-	    write_bytes = num_pages * PAGE_CACHE_SIZE - 
-			    (pos & (PAGE_CACHE_SIZE-1));
-					 /* If position is not on the
-					    start of the page, we need
-					    to substract the offset
-					    within page */
-	} else
-	    write_bytes = count;
-
-	/* reserve the blocks to be allocated later, so that later on
-	   we still have the space to write the blocks to */
-	reiserfs_claim_blocks_to_be_allocated(inode->i_sb, num_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize));
-	unlock_kernel();
-
-	if ( !num_pages ) { /* If we do not have enough space even for */
-	    res = -ENOSPC;  /* single page, return -ENOSPC */
-	    if ( pos > (inode->i_size & (inode->i_sb->s_blocksize-1)))
-		break; // In case we are writing past the file end, break.
-	    // Otherwise we are possibly overwriting the file, so
-	    // let's set write size to be equal or less than blocksize.
-	    // This way we get it correctly for file holes.
-	    // But overwriting files on absolutelly full volumes would not
-	    // be very efficient. Well, people are not supposed to fill
-	    // 100% of disk space anyway.
-	    write_bytes = min_t(int, count, inode->i_sb->s_blocksize - (pos & (inode->i_sb->s_blocksize - 1)));
-	    num_pages = 1;
-	}
-
-	/* Prepare for writing into the region, read in all the
-	   partially overwritten pages, if needed. And lock the pages,
-	   so that nobody else can access these until we are done.
-	   We get number of actual blocks needed as a result.*/
-	blocks_to_allocate = reiserfs_prepare_file_region_for_write(inode, pos, num_pages, write_bytes, prepared_pages);
-	if ( blocks_to_allocate < 0 ) {
-	    res = blocks_to_allocate;
-	    reiserfs_release_claimed_blocks(inode->i_sb, num_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize));
-	    break;
-	}
-
-	/* First we correct our estimate of how many blocks we need */
-	reiserfs_release_claimed_blocks(inode->i_sb, num_pages * (PAGE_CACHE_SIZE>>inode->i_sb->s_blocksize_bits) - blocks_to_allocate );
-
-	if ( blocks_to_allocate > 0) {/*We only allocate blocks if we need to*/
-	    /* Fill in all the possible holes and append the file if needed */
-	    res = reiserfs_allocate_blocks_for_region(inode, pos, num_pages, write_bytes, prepared_pages, blocks_to_allocate);
-	} else if ( pos + write_bytes > inode->i_size ) {
-	    /* File might have grown even though no new blocks were added */
-	    inode->i_size = pos + write_bytes;
-	    inode->i_sb->s_op->dirty_inode(inode);
-	}
-
-	/* well, we have allocated the blocks, so it is time to free
-	   the reservation we made earlier. */
-	reiserfs_release_claimed_blocks(inode->i_sb, blocks_to_allocate);
-	if ( res ) {
-	    reiserfs_unprepare_pages(prepared_pages, num_pages);
-	    break;
-	}
-
-/* NOTE that allocating blocks and filling blocks can be done in reverse order
-   and probably we would do that just to get rid of garbage in files after a
-   crash */
-
-	/* Copy data from user-supplied buffer to file's pages */
-	res = reiserfs_copy_from_user_to_file_region(pos, num_pages, write_bytes, prepared_pages, buf);
-	if ( res ) {
-	    reiserfs_unprepare_pages(prepared_pages, num_pages);
-	    break;
-	}
-
-	/* Send the pages to disk and unlock them. */
-	res = reiserfs_submit_file_region_for_write(pos, num_pages, write_bytes, prepared_pages);
-	if ( res )
-	    break;
-
-	already_written += write_bytes;
-	buf += write_bytes;
-	pos = *ppos += write_bytes;
-	count -= write_bytes;
-    }
-
-    if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
-	res = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
-
-    up(&inode->i_sem);
-    return (already_written != 0)?already_written:res;
-
-out:
-    up(&inode->i_sem); // unlock the file on exit.
-    return res;
-}
 struct file_operations reiserfs_file_operations = {
     read:	generic_file_read,
-    write:	reiserfs_file_write,
+    write:	generic_file_write,
     ioctl:	reiserfs_ioctl,
     mmap:	generic_file_mmap,
     release:	reiserfs_file_release,
diff -urN linux-2.4.20-pre6/fs/reiserfs/inode.c linux-2.4.20-pre7/fs/reiserfs/inode.c
--- linux-2.4.20-pre6/fs/reiserfs/inode.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/reiserfs/inode.c	Thu Sep 12 20:01:49 2002
@@ -774,69 +774,36 @@
 	       pointer to 'block'-th block use block, which is already
 	       allocated */
 	    struct cpu_key tmp_key;
-	    unp_t unf_single=0; // We use this in case we need to allocate only
-				// one block which is a fastpath
-	    unp_t *un;
-	    __u64 max_to_insert=MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE;
-	    __u64 blocks_needed;
+	    struct unfm_nodeinfo un = {0, 0};
 
 	    RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
 		    "vs-804: invalid position for append");
-	    
 	    /* indirect item has to be appended, set up key of that position */
 	    make_cpu_key (&tmp_key, inode,
 			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),
 			  //pos_in_item * inode->i_sb->s_blocksize,
 			  TYPE_INDIRECT, 3);// key type is unimportant
-
-	    blocks_needed = 1 + ((cpu_key_k_offset (&key) - cpu_key_k_offset (&tmp_key)) >> inode->i_sb->s_blocksize_bits);
-	    RFALSE( blocks_needed < 0, "green-805: invalid offset");
-
-	    if ( blocks_needed == 1 ) {
-		un = &unf_single;
-	    } else {
-		un=kmalloc( min(blocks_needed,max_to_insert)*UNFM_P_SIZE,
-			    GFP_ATOMIC); // We need to avoid scheduling.
-		if ( !un) {
-		    un = &unf_single;
-		    blocks_needed = 1;
-		    max_to_insert = 0;
-		} else 
-		    memset(un, 0, UNFM_P_SIZE * min(blocks_needed,max_to_insert));
-	    }
-	    if ( blocks_needed <= max_to_insert) {
+		  
+	    if (cpu_key_k_offset (&tmp_key) == cpu_key_k_offset (&key)) {
 		/* we are going to add target block to the file. Use allocated
 		   block for that */
-		un[blocks_needed-1] = cpu_to_le32 (allocated_block_nr);
+		un.unfm_nodenum = cpu_to_le32 (allocated_block_nr);
 		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
 		bh_result->b_state |= (1UL << BH_New);
 		done = 1;
 	    } else {
 		/* paste hole to the indirect item */
-		// If kmalloc failed, max_to_insert becomes zero and it means we
-		// only have space for one block
-		blocks_needed=max_to_insert?max_to_insert:1;
 	    }
-	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)un, UNFM_P_SIZE * blocks_needed);
-
-	    if (blocks_needed != 1)
-		kfree(un);
-
+	    retval = reiserfs_paste_into_item (&th, &path, &tmp_key, (char *)&un, UNFM_P_SIZE);
 	    if (retval) {
 		reiserfs_free_block (&th, allocated_block_nr);
 		goto failure;
 	    }
-	    if (done) {
+	    if (un.unfm_nodenum)
 		inode->i_blocks += inode->i_sb->s_blocksize / 512;
-	    } else {
-		// We need to mark new file size in case this function will be
-		// interrupted/aborted later on. And we may do this only for
-		// holes.
-		inode->i_size += inode->i_sb->s_blocksize * blocks_needed;
-	    }
 	    //mark_tail_converted (inode);
 	}
-
+		
 	if (done == 1)
 	    break;
 	 
@@ -913,7 +880,7 @@
 
 
     copy_key (INODE_PKEY (inode), &(ih->ih_key));
-    inode->i_blksize = PAGE_SIZE*32;
+    inode->i_blksize = PAGE_SIZE;
 
     INIT_LIST_HEAD(&inode->u.reiserfs_i.i_prealloc_list) ;
 
@@ -1605,7 +1572,7 @@
 
     // these do not go to on-disk stat data
     inode->i_ino = le32_to_cpu (ih.ih_key.k_objectid);
-    inode->i_blksize = PAGE_SIZE*32;
+    inode->i_blksize = PAGE_SIZE;
     inode->i_dev = sb->s_dev;
   
     // store in in-core inode the key of stat data and version all
diff -urN linux-2.4.20-pre6/fs/reiserfs/super.c linux-2.4.20-pre7/fs/reiserfs/super.c
--- linux-2.4.20-pre6/fs/reiserfs/super.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/reiserfs/super.c	Thu Sep 12 20:01:49 2002
@@ -1266,7 +1266,6 @@
     reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc );
     reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
     init_waitqueue_head (&(s->u.reiserfs_sb.s_wait));
-    s->u.reiserfs_sb.bitmap_lock = SPIN_LOCK_UNLOCKED;
 
     printk("%s\n", reiserfs_get_version_string()) ;
     return s;
diff -urN linux-2.4.20-pre6/fs/reiserfs/tail_conversion.c linux-2.4.20-pre7/fs/reiserfs/tail_conversion.c
--- linux-2.4.20-pre6/fs/reiserfs/tail_conversion.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/fs/reiserfs/tail_conversion.c	Thu Sep 12 20:01:49 2002
@@ -30,7 +30,7 @@
                                 key of unfm pointer to be pasted */
     int	n_blk_size,
       n_retval;	  /* returned value for reiserfs_insert_item and clones */
-    unp_t unfm_ptr;  /* Handle on an unformatted node
+    struct unfm_nodeinfo unfm_ptr;  /* Handle on an unformatted node
 				       that will be inserted in the
 				       tree. */
 
@@ -59,7 +59,8 @@
     
     p_le_ih = PATH_PITEM_HEAD (path);
 
-    unfm_ptr = cpu_to_le32 (unbh->b_blocknr);
+    unfm_ptr.unfm_nodenum = cpu_to_le32 (unbh->b_blocknr);
+    unfm_ptr.unfm_freespace = 0; // ???
     
     if ( is_statdata_le_ih (p_le_ih) )  {
 	/* Insert new indirect item. */
diff -urN linux-2.4.20-pre6/include/asm-alpha/rwsem.h linux-2.4.20-pre7/include/asm-alpha/rwsem.h
--- linux-2.4.20-pre6/include/asm-alpha/rwsem.h	Fri Oct  5 12:10:00 2001
+++ linux-2.4.20-pre7/include/asm-alpha/rwsem.h	Thu Sep 12 20:01:49 2002
@@ -87,6 +87,24 @@
 		rwsem_down_read_failed(sem);
 }
 
+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+	long old, new, res;
+
+	res = sem->count;
+	do {
+		new = res + RWSEM_ACTIVE_READ_BIAS;
+		if (new <= 0)
+			break;
+		old = res;
+		res = cmpxchg(&sem->count, old, new);
+	} while (res != old);
+	return res >= 0 ? 1 : 0;
+}
+
 static inline void __down_write(struct rw_semaphore *sem)
 {
 	long oldcount;
@@ -111,6 +129,18 @@
 		rwsem_down_write_failed(sem);
 }
 
+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+	long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+			   RWSEM_ACTIVE_WRITE_BIAS);
+	if (ret == RWSEM_UNLOCKED_VALUE)
+		return 1;
+	return 0;
+}
+
 static inline void __up_read(struct rw_semaphore *sem)
 {
 	long oldcount;
diff -urN linux-2.4.20-pre6/include/asm-i386/unistd.h linux-2.4.20-pre7/include/asm-i386/unistd.h
--- linux-2.4.20-pre6/include/asm-i386/unistd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-i386/unistd.h	Thu Sep 12 20:01:49 2002
@@ -247,6 +247,16 @@
 #define __NR_futex		240
 #define __NR_sched_setaffinity	241
 #define __NR_sched_getaffinity	242
+#define __NR_set_thread_area	243
+#define __NR_get_thread_area	244
+#define __NR_io_setup		245
+#define __NR_io_destroy		246
+#define __NR_io_getevents	247
+#define __NR_io_submit		248
+#define __NR_io_cancel		249
+#define __NR_alloc_hugepages	250
+#define __NR_free_hugepages	251
+#define __NR_exit_group		252
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -urN linux-2.4.20-pre6/include/asm-ia64/acpi-ext.h linux-2.4.20-pre7/include/asm-ia64/acpi-ext.h
--- linux-2.4.20-pre6/include/asm-ia64/acpi-ext.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/acpi-ext.h	Wed Dec 31 16:00:00 1969
@@ -1,323 +0,0 @@
-#ifndef _ASM_IA64_ACPI_EXT_H
-#define _ASM_IA64_ACPI_EXT_H
-
-/*
- * Advanced Configuration and Power Infterface
- * Based on 'ACPI Specification 1.0b' Febryary 2, 1999
- * and 'IA-64 Extensions to the ACPI Specification' Rev 0.6
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 2000 Intel Corp.
- * Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
- *	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 */
-#define ACPI_RSDP_SIG_LEN 8
-typedef struct {
-	char signature[8];
-	u8 checksum;
-	char oem_id[6];
-	u8 revision;
-	u32 rsdt;
-	u32 length;
-	struct acpi_xsdt *xsdt;
-	u8 ext_checksum;
-	u8 reserved[3];
-} acpi20_rsdp_t;
-
-typedef struct {
-	char signature[4];
-	u32 length;
-	u8 revision;
-	u8 checksum;
-	char oem_id[6];
-	char oem_table_id[8];
-	u32 oem_revision;
-	u32 creator_id;
-	u32 creator_revision;
-} acpi_desc_table_hdr_t;
-
-#define ACPI_RSDT_SIG "RSDT"
-#define ACPI_RSDT_SIG_LEN 4
-typedef struct {
-	acpi_desc_table_hdr_t header;
-	u8 reserved[4];
-	u32 entry_ptrs[1];	/* Not really . . . */
-} acpi20_rsdt_t;
-
-#define ACPI_XSDT_SIG "XSDT"
-#define ACPI_XSDT_SIG_LEN 4
-typedef struct acpi_xsdt {
-	acpi_desc_table_hdr_t header;
-	unsigned long entry_ptrs[1];	/* Not really . . . */
-} acpi_xsdt_t;
-
-/* Common structures for ACPI 2.0 and 0.71 */
-
-typedef struct acpi_entry_iosapic {
-	u8 type;
-	u8 length;
-	u8 id;
-	u8 reserved;
-	u32 irq_base;	/* start of IRQ's this IOSAPIC is responsible for. */
-	unsigned long address;	/* Address of this IOSAPIC */
-} acpi_entry_iosapic_t;
-
-/* Local SAPIC flags */
-#define LSAPIC_ENABLED                (1<<0)
-#define LSAPIC_PERFORMANCE_RESTRICTED (1<<1)
-#define LSAPIC_PRESENT                (1<<2)
-
-/* Defines legacy IRQ->pin mapping */
-typedef struct {
-	u8 type;
-	u8 length;
-	u8 bus;		/* Constant 0 == ISA */
-	u8 isa_irq;	/* ISA IRQ # */
-	u32 pin;		/* called vector in spec; really IOSAPIC pin number */
-	u16 flags;	/* Edge/Level trigger & High/Low active */
-} acpi_entry_int_override_t;
-
-#define INT_OVERRIDE_ACTIVE_LOW    0x03
-#define INT_OVERRIDE_LEVEL_TRIGGER 0x0d
-
-/* IA64 ext 0.71 */
-
-typedef struct {
-	char signature[8];
-	u8 checksum;
-	char oem_id[6];
-	char reserved;		/* Must be 0 */
-	struct acpi_rsdt *rsdt;
-} acpi_rsdp_t;
-
-typedef struct acpi_rsdt {
-	acpi_desc_table_hdr_t header;
-	u8 reserved[4];
-	unsigned long entry_ptrs[1];	/* Not really . . . */
-} acpi_rsdt_t;
-
-#define ACPI_SAPIC_SIG "SPIC"
-#define ACPI_SAPIC_SIG_LEN 4
-typedef struct {
-	acpi_desc_table_hdr_t header;
-	u8 reserved[4];
-	unsigned long interrupt_block;
-} acpi_sapic_t;
-
-/* SAPIC structure types */
-#define ACPI_ENTRY_LOCAL_SAPIC         0
-#define ACPI_ENTRY_IO_SAPIC            1
-#define ACPI_ENTRY_INT_SRC_OVERRIDE    2
-#define ACPI_ENTRY_PLATFORM_INT_SOURCE 3	/* Unimplemented */
-
-typedef struct acpi_entry_lsapic {
-	u8 type;
-	u8 length;
-	u16 acpi_processor_id;
-	u16 flags;
-	u8 id;
-	u8 eid;
-} acpi_entry_lsapic_t;
-
-typedef struct {
-	u8 type;
-	u8 length;
-	u16 flags;
-	u8 int_type;
-	u8 id;
-	u8 eid;
-	u8 iosapic_vector;
-	u8 reserved[4];
-	u32 global_vector;
-} acpi_entry_platform_src_t;
-
-/* ACPI 2.0 with 1.3 errata specific structures */
-
-#define ACPI_MADT_SIG "APIC"
-#define ACPI_MADT_SIG_LEN 4
-typedef struct {
-	acpi_desc_table_hdr_t header;
-	u32 lapic_address;
-	u32 flags;
-} acpi_madt_t;
-
-/* acpi 2.0 MADT flags */
-#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
-
-typedef struct acpi20_entry_lsapic {
-	u8 type;
-	u8 length;
-	u8 acpi_processor_id;
-	u8 id;
-	u8 eid;
-	u8 reserved[3];
-	u32 flags;
-} acpi20_entry_lsapic_t;
-
-typedef struct acpi20_entry_lapic_addr_override {
-	u8 type;
-	u8 length;
-	u8 reserved[2];
-	unsigned long lapic_address;
-} acpi20_entry_lapic_addr_override_t;
-
-typedef struct {
-	u8 type;
-	u8 length;
-	u16 flags;
-	u8 int_type;
-	u8 id;
-	u8 eid;
-	u8 iosapic_vector;
-	u32 global_vector;
-} 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 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 -urN linux-2.4.20-pre6/include/asm-ia64/acpi.h linux-2.4.20-pre7/include/asm-ia64/acpi.h
--- linux-2.4.20-pre6/include/asm-ia64/acpi.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-ia64/acpi.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,114 @@
+/*
+ *  asm-ia64/acpi.h
+ *
+ *  Copyright (C) 1999 VA Linux Systems
+ *  Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
+ *  Copyright (C) 2001,2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.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_ACPI_H
+#define _ASM_ACPI_H
+
+#ifdef __KERNEL__
+
+#define COMPILER_DEPENDENT_INT64	long
+#define COMPILER_DEPENDENT_UINT64	unsigned long
+
+/*
+ * Calling conventions:
+ *
+ * ACPI_SYSTEM_XFACE        - Interfaces to host OS (handlers, threads)
+ * ACPI_EXTERNAL_XFACE      - External ACPI interfaces
+ * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
+ * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
+ */
+#define ACPI_SYSTEM_XFACE
+#define ACPI_EXTERNAL_XFACE
+#define ACPI_INTERNAL_XFACE
+#define ACPI_INTERNAL_VAR_XFACE
+
+/* Asm macros */
+
+#define ACPI_ASM_MACROS
+#define BREAKPOINT3
+#define ACPI_DISABLE_IRQS() __cli()
+#define ACPI_ENABLE_IRQS()  __sti()
+#define ACPI_FLUSH_CPU_CACHE()
+
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+	__asm__ volatile ("1:  ld4      r29=%1\n"  \
+		";;\n"                  \
+		"mov    ar.ccv=r29\n"   \
+		"mov    r2=r29\n"       \
+		"shr.u  r30=r29,1\n"    \
+		"and    r29=-4,r29\n"   \
+		";;\n"                  \
+		"add    r29=2,r29\n"    \
+		"and    r30=1,r30\n"    \
+		";;\n"                  \
+		"add    r29=r29,r30\n"  \
+		";;\n"                  \
+		"cmpxchg4.acq   r30=%1,r29,ar.ccv\n" \
+		";;\n"                  \
+		"cmp.eq p6,p7=r2,r30\n" \
+		"(p7) br.dpnt.few 1b\n" \
+		"cmp.gt p8,p9=3,r29\n"  \
+		";;\n"                  \
+		"(p8) mov %0=-1\n"      \
+		"(p9) mov %0=r0\n"      \
+		:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
+	} while (0)
+
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+	__asm__ volatile ("1:  ld4      r29=%1\n" \
+		";;\n"                  \
+		"mov    ar.ccv=r29\n"   \
+		"mov    r2=r29\n"       \
+		"and    r29=-4,r29\n"   \
+		";;\n"                  \
+		"cmpxchg4.acq   r30=%1,r29,ar.ccv\n" \
+		";;\n"                  \
+		"cmp.eq p6,p7=r2,r30\n" \
+		"(p7) br.dpnt.few 1b\n" \
+		"and    %0=1,r2\n"      \
+		";;\n"                  \
+		:"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \
+	} while (0)
+
+const char *acpi_get_sysname (void);
+int acpi_boot_init (char *cdline);
+int acpi_request_vector (u32 int_type);
+int acpi_get_prt (struct pci_vector_struct **vectors, int *count);
+int acpi_get_interrupt_model (int *type);
+int acpi_irq_to_vector (u32 irq);
+
+#ifdef CONFIG_DISCONTIGMEM
+#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)
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /*__KERNEL__*/
+
+#endif /*_ASM_ACPI_H*/
diff -urN linux-2.4.20-pre6/include/asm-ia64/acpikcfg.h linux-2.4.20-pre7/include/asm-ia64/acpikcfg.h
--- linux-2.4.20-pre6/include/asm-ia64/acpikcfg.h	Tue Jul 31 10:30:09 2001
+++ linux-2.4.20-pre7/include/asm-ia64/acpikcfg.h	Wed Dec 31 16:00:00 1969
@@ -1,30 +0,0 @@
-#ifndef _ASM_IA64_ACPIKCFG_H
-#define _ASM_IA64_ACPIKCFG_H
-
-/*
- *  acpikcfg.h - ACPI based Kernel Configuration Manager External Interfaces
- *
- *  Copyright (C) 2000 Intel Corp.
- *  Copyright (C) 2000 J.I. Lee  <jung-ik.lee@intel.com>
- */
-
-
-u32	__init acpi_cf_init (void * rsdp);
-u32	__init acpi_cf_terminate (void );
-
-u32	__init
-acpi_cf_get_pci_vectors (
-	struct pci_vector_struct	**vectors,
-	int				*num_pci_vectors
-	);
-
-
-#ifdef	CONFIG_ACPI_KERNEL_CONFIG_DEBUG
-void	__init
-acpi_cf_print_pci_vectors (
-	struct pci_vector_struct	*vectors,
-	int				num_pci_vectors
-	);
-#endif
-
-#endif /* _ASM_IA64_ACPIKCFG_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/atomic.h linux-2.4.20-pre7/include/asm-ia64/atomic.h
--- linux-2.4.20-pre6/include/asm-ia64/atomic.h	Mon Jul  9 21:30:19 2001
+++ linux-2.4.20-pre7/include/asm-ia64/atomic.h	Thu Sep 12 20:01:49 2002
@@ -9,8 +9,8 @@
  * "int" types were carefully placed so as to ensure proper operation
  * of the macros.
  *
- * 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 <linux/types.h>
 
diff -urN linux-2.4.20-pre6/include/asm-ia64/bitops.h linux-2.4.20-pre7/include/asm-ia64/bitops.h
--- linux-2.4.20-pre6/include/asm-ia64/bitops.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/bitops.h	Thu Sep 12 20:01:49 2002
@@ -325,7 +325,7 @@
 /*
  * Find next zero bit in a bitmap reasonably efficiently..
  */
-static inline int
+static inline unsigned long
 find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
diff -urN linux-2.4.20-pre6/include/asm-ia64/cache.h linux-2.4.20-pre7/include/asm-ia64/cache.h
--- linux-2.4.20-pre6/include/asm-ia64/cache.h	Thu Apr  5 12:51:47 2001
+++ linux-2.4.20-pre7/include/asm-ia64/cache.h	Thu Sep 12 20:01:49 2002
@@ -5,7 +5,7 @@
 
 /*
  * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 /* Bytes per L1 (data) cache line.  */
diff -urN linux-2.4.20-pre6/include/asm-ia64/current.h linux-2.4.20-pre7/include/asm-ia64/current.h
--- linux-2.4.20-pre6/include/asm-ia64/current.h	Fri Apr 21 15:21:24 2000
+++ linux-2.4.20-pre7/include/asm-ia64/current.h	Thu Sep 12 20:01:49 2002
@@ -3,7 +3,7 @@
 
 /*
  * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 /* In kernel mode, thread pointer (r13) is used to point to the
diff -urN linux-2.4.20-pre6/include/asm-ia64/elf.h linux-2.4.20-pre7/include/asm-ia64/elf.h
--- linux-2.4.20-pre6/include/asm-ia64/elf.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/elf.h	Thu Sep 12 20:01:49 2002
@@ -39,7 +39,7 @@
  * the way of the program that it will "exec", and that there is
  * sufficient room for the brk.
  */
-#define ELF_ET_DYN_BASE		(TASK_UNMAPPED_BASE + 0x1000000)
+#define ELF_ET_DYN_BASE		(TASK_UNMAPPED_BASE + 0x800000000)
 
 
 /*
diff -urN linux-2.4.20-pre6/include/asm-ia64/errno.h linux-2.4.20-pre7/include/asm-ia64/errno.h
--- linux-2.4.20-pre6/include/asm-ia64/errno.h	Tue Apr 10 12:23:06 2001
+++ linux-2.4.20-pre7/include/asm-ia64/errno.h	Thu Sep 12 20:01:49 2002
@@ -14,7 +14,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 -urN linux-2.4.20-pre6/include/asm-ia64/hw_irq.h linux-2.4.20-pre7/include/asm-ia64/hw_irq.h
--- linux-2.4.20-pre6/include/asm-ia64/hw_irq.h	Tue Jul 31 10:30:09 2001
+++ linux-2.4.20-pre7/include/asm-ia64/hw_irq.h	Thu Sep 12 20:01:49 2002
@@ -2,8 +2,8 @@
 #define _ASM_IA64_HW_IRQ_H
 
 /*
- * Copyright (C) 2001 Hewlett-Packard Co
- * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2001, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/sched.h>
@@ -52,6 +52,10 @@
 #define IA64_IPI_RESCHEDULE		0xfd	/* SMP reschedule */
 #define IA64_IPI_VECTOR			0xfe	/* inter-processor interrupt vector */
 
+/* Used for encoding redirected irqs */
+
+#define IA64_IRQ_REDIRECTED		(1 << 31)
+
 /* IA64 inter-cpu interrupt related definitions */
 
 #define IA64_IPI_DEFAULT_BASE_ADDR	0xfee00000
@@ -72,7 +76,7 @@
 
 extern struct hw_interrupt_type irq_type_ia64_lsapic;	/* CPU-internal interrupt controller */
 
-extern int ia64_alloc_irq (void);	/* allocate a free irq */
+extern int ia64_alloc_vector (void);	/* allocate a free vector */
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
 extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
 
@@ -88,6 +92,7 @@
 
 extern struct irq_desc _irq_desc[NR_IRQS];
 
+#ifndef CONFIG_IA64_GENERIC
 static inline struct irq_desc *
 __ia64_irq_desc (unsigned int irq)
 {
@@ -105,6 +110,7 @@
 {
 	return (unsigned int) vec;
 }
+#endif
 
 /*
  * Next follows the irq descriptor interface.  On IA-64, each CPU supports 256 interrupt
diff -urN linux-2.4.20-pre6/include/asm-ia64/ide.h linux-2.4.20-pre7/include/asm-ia64/ide.h
--- linux-2.4.20-pre6/include/asm-ia64/ide.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/ide.h	Thu Sep 12 20:01:49 2002
@@ -27,8 +27,7 @@
 
 #define ide__sti()	__sti()
 
-static __inline__ int
-ide_default_irq (ide_ioreg_t base)
+static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
 	switch (base) {
 		case 0x1f0: return isa_irq_to_vector(14);
@@ -42,8 +41,7 @@
 	}
 }
 
-static __inline__ ide_ioreg_t
-ide_default_io_base (int index)
+static __inline__ ide_ioreg_t ide_default_io_base(int index)
 {
 	switch (index) {
 		case 0:	return 0x1f0;
@@ -57,8 +55,7 @@
 	}
 }
 
-static __inline__ void
-ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+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;
@@ -77,8 +74,7 @@
 	hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
-static __inline__ void
-ide_init_default_hwifs (void)
+static __inline__ void ide_init_default_hwifs(void)
 {
 #ifndef CONFIG_BLK_DEV_IDEPCI
 	hw_regs_t hw;
diff -urN linux-2.4.20-pre6/include/asm-ia64/ioctls.h linux-2.4.20-pre7/include/asm-ia64/ioctls.h
--- linux-2.4.20-pre6/include/asm-ia64/ioctls.h	Sun Feb  6 18:42:40 2000
+++ linux-2.4.20-pre7/include/asm-ia64/ioctls.h	Thu Sep 12 20:01:49 2002
@@ -11,7 +11,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 -urN linux-2.4.20-pre6/include/asm-ia64/iosapic.h linux-2.4.20-pre7/include/asm-ia64/iosapic.h
--- linux-2.4.20-pre6/include/asm-ia64/iosapic.h	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/include/asm-ia64/iosapic.h	Thu Sep 12 20:01:49 2002
@@ -51,17 +51,24 @@
 
 #ifndef __ASSEMBLY__
 
-extern void __init iosapic_init (unsigned long address, unsigned int base_irq,
-                                 int pcat_compat);
-extern int iosapic_register_irq (u32 global_vector, unsigned long polarity,
-                                 unsigned long edge_triggered, u32 base_irq,
-                                 char *iosapic_address);
-extern void iosapic_register_legacy_irq (unsigned long irq, unsigned long pin,
-					 unsigned long polarity, unsigned long trigger);
-extern int 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);
+extern void __devinit iosapic_init (unsigned long address,
+				    unsigned int gsi_base,
+				    int pcat_compat);
+extern int gsi_to_vector (unsigned int gsi);
+extern int iosapic_register_intr (unsigned int gsi, unsigned long polarity,
+				  unsigned long edge_triggered,
+				  u32 gsi_base, char *iosapic_address);
+extern void iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
+				      unsigned long polarity,
+				      unsigned long edge_triggered);
+extern int iosapic_register_platform_intr (u32 int_type,
+					   unsigned int gsi,
+					   int pmi_vector,
+					   u16 eid, u16 id,
+					   unsigned long polarity,
+					   unsigned long edge_triggered,
+					   unsigned int gsi_base,
+					   char *iosapic_address);
 extern unsigned int iosapic_version (char *addr);
 
 extern void iosapic_pci_fixup (int);
diff -urN linux-2.4.20-pre6/include/asm-ia64/keyboard.h linux-2.4.20-pre7/include/asm-ia64/keyboard.h
--- linux-2.4.20-pre6/include/asm-ia64/keyboard.h	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/include/asm-ia64/keyboard.h	Thu Sep 12 20:01:49 2002
@@ -16,6 +16,7 @@
 #define KEYBOARD_IRQ			isa_irq_to_vector(1)
 #define DISABLE_KBD_DURING_INTERRUPTS	0
 
+extern unsigned char acpi_kbd_controller_present;
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
 extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
@@ -26,6 +27,7 @@
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
 
+#define kbd_controller_present() acpi_kbd_controller_present
 #define kbd_setkeycode		pckbd_setkeycode
 #define kbd_getkeycode		pckbd_getkeycode
 #define kbd_pretranslate	pckbd_pretranslate
diff -urN linux-2.4.20-pre6/include/asm-ia64/kregs.h linux-2.4.20-pre7/include/asm-ia64/kregs.h
--- linux-2.4.20-pre6/include/asm-ia64/kregs.h	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/include/asm-ia64/kregs.h	Thu Sep 12 20:01:49 2002
@@ -2,8 +2,8 @@
 #define _ASM_IA64_KREGS_H
 
 /*
- * Copyright (C) 2001 Hewlett-Packard Co
- * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2001-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
  * This file defines the kernel register usage convention used by Linux/ia64.
@@ -31,4 +31,132 @@
 #define IA64_TR_PERCPU_DATA	1	/* dtr1: percpu data */
 #define IA64_TR_CURRENT_STACK	2	/* dtr2: maps kernel's memory- & register-stacks */
 
-#endif /* _ASM_IA64_kREGS_H */
+/* Processor status register bits: */
+#define IA64_PSR_BE_BIT		1
+#define IA64_PSR_UP_BIT		2
+#define IA64_PSR_AC_BIT		3
+#define IA64_PSR_MFL_BIT	4
+#define IA64_PSR_MFH_BIT	5
+#define IA64_PSR_IC_BIT		13
+#define IA64_PSR_I_BIT		14
+#define IA64_PSR_PK_BIT		15
+#define IA64_PSR_DT_BIT		17
+#define IA64_PSR_DFL_BIT	18
+#define IA64_PSR_DFH_BIT	19
+#define IA64_PSR_SP_BIT		20
+#define IA64_PSR_PP_BIT		21
+#define IA64_PSR_DI_BIT		22
+#define IA64_PSR_SI_BIT		23
+#define IA64_PSR_DB_BIT		24
+#define IA64_PSR_LP_BIT		25
+#define IA64_PSR_TB_BIT		26
+#define IA64_PSR_RT_BIT		27
+/* The following are not affected by save_flags()/restore_flags(): */
+#define IA64_PSR_CPL0_BIT	32
+#define IA64_PSR_CPL1_BIT	33
+#define IA64_PSR_IS_BIT		34
+#define IA64_PSR_MC_BIT		35
+#define IA64_PSR_IT_BIT		36
+#define IA64_PSR_ID_BIT		37
+#define IA64_PSR_DA_BIT		38
+#define IA64_PSR_DD_BIT		39
+#define IA64_PSR_SS_BIT		40
+#define IA64_PSR_RI_BIT		41
+#define IA64_PSR_ED_BIT		43
+#define IA64_PSR_BN_BIT		44
+#define IA64_PSR_IA_BIT		45
+
+#define IA64_PSR_BE	(__IA64_UL(1) << IA64_PSR_BE_BIT)
+#define IA64_PSR_UP	(__IA64_UL(1) << IA64_PSR_UP_BIT)
+#define IA64_PSR_AC	(__IA64_UL(1) << IA64_PSR_AC_BIT)
+#define IA64_PSR_MFL	(__IA64_UL(1) << IA64_PSR_MFL_BIT)
+#define IA64_PSR_MFH	(__IA64_UL(1) << IA64_PSR_MFH_BIT)
+#define IA64_PSR_IC	(__IA64_UL(1) << IA64_PSR_IC_BIT)
+#define IA64_PSR_I	(__IA64_UL(1) << IA64_PSR_I_BIT)
+#define IA64_PSR_PK	(__IA64_UL(1) << IA64_PSR_PK_BIT)
+#define IA64_PSR_DT	(__IA64_UL(1) << IA64_PSR_DT_BIT)
+#define IA64_PSR_DFL	(__IA64_UL(1) << IA64_PSR_DFL_BIT)
+#define IA64_PSR_DFH	(__IA64_UL(1) << IA64_PSR_DFH_BIT)
+#define IA64_PSR_SP	(__IA64_UL(1) << IA64_PSR_SP_BIT)
+#define IA64_PSR_PP	(__IA64_UL(1) << IA64_PSR_PP_BIT)
+#define IA64_PSR_DI	(__IA64_UL(1) << IA64_PSR_DI_BIT)
+#define IA64_PSR_SI	(__IA64_UL(1) << IA64_PSR_SI_BIT)
+#define IA64_PSR_DB	(__IA64_UL(1) << IA64_PSR_DB_BIT)
+#define IA64_PSR_LP	(__IA64_UL(1) << IA64_PSR_LP_BIT)
+#define IA64_PSR_TB	(__IA64_UL(1) << IA64_PSR_TB_BIT)
+#define IA64_PSR_RT	(__IA64_UL(1) << IA64_PSR_RT_BIT)
+/* The following are not affected by save_flags()/restore_flags(): */
+#define IA64_PSR_CPL	(__IA64_UL(3) << IA64_PSR_CPL0_BIT)
+#define IA64_PSR_IS	(__IA64_UL(1) << IA64_PSR_IS_BIT)
+#define IA64_PSR_MC	(__IA64_UL(1) << IA64_PSR_MC_BIT)
+#define IA64_PSR_IT	(__IA64_UL(1) << IA64_PSR_IT_BIT)
+#define IA64_PSR_ID	(__IA64_UL(1) << IA64_PSR_ID_BIT)
+#define IA64_PSR_DA	(__IA64_UL(1) << IA64_PSR_DA_BIT)
+#define IA64_PSR_DD	(__IA64_UL(1) << IA64_PSR_DD_BIT)
+#define IA64_PSR_SS	(__IA64_UL(1) << IA64_PSR_SS_BIT)
+#define IA64_PSR_RI	(__IA64_UL(3) << IA64_PSR_RI_BIT)
+#define IA64_PSR_ED	(__IA64_UL(1) << IA64_PSR_ED_BIT)
+#define IA64_PSR_BN	(__IA64_UL(1) << IA64_PSR_BN_BIT)
+#define IA64_PSR_IA	(__IA64_UL(1) << IA64_PSR_IA_BIT)
+
+/* A mask of PSR bits that we generally don't want to inherit across a clone2() or an
+   execve().  Only list flags here that need to be cleared/set for BOTH clone2() and
+   execve().  */
+#define IA64_PSR_BITS_TO_CLEAR	(IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_DB | IA64_PSR_LP | \
+				 IA64_PSR_TB  | IA64_PSR_ID  | IA64_PSR_DA | IA64_PSR_DD | \
+				 IA64_PSR_SS  | IA64_PSR_ED  | IA64_PSR_IA)
+#define IA64_PSR_BITS_TO_SET	(IA64_PSR_DFH)
+
+/* User mask bits: */
+#define IA64_PSR_UM	(IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC | IA64_PSR_MFL | IA64_PSR_MFH)
+
+/* Default Control Register */
+#define IA64_DCR_PP_BIT		 0	/* privileged performance monitor default */
+#define IA64_DCR_BE_BIT		 1	/* big-endian default */
+#define IA64_DCR_LC_BIT		 2	/* ia32 lock-check enable */
+#define IA64_DCR_DM_BIT		 8	/* defer TLB miss faults */
+#define IA64_DCR_DP_BIT		 9	/* defer page-not-present faults */
+#define IA64_DCR_DK_BIT		10	/* defer key miss faults */
+#define IA64_DCR_DX_BIT		11	/* defer key permission faults */
+#define IA64_DCR_DR_BIT		12	/* defer access right faults */
+#define IA64_DCR_DA_BIT		13	/* defer access bit faults */
+#define IA64_DCR_DD_BIT		14	/* defer debug faults */
+
+#define IA64_DCR_PP	(__IA64_UL(1) << IA64_DCR_PP_BIT)
+#define IA64_DCR_BE	(__IA64_UL(1) << IA64_DCR_BE_BIT)
+#define IA64_DCR_LC	(__IA64_UL(1) << IA64_DCR_LC_BIT)
+#define IA64_DCR_DM	(__IA64_UL(1) << IA64_DCR_DM_BIT)
+#define IA64_DCR_DP	(__IA64_UL(1) << IA64_DCR_DP_BIT)
+#define IA64_DCR_DK	(__IA64_UL(1) << IA64_DCR_DK_BIT)
+#define IA64_DCR_DX	(__IA64_UL(1) << IA64_DCR_DX_BIT)
+#define IA64_DCR_DR	(__IA64_UL(1) << IA64_DCR_DR_BIT)
+#define IA64_DCR_DA	(__IA64_UL(1) << IA64_DCR_DA_BIT)
+#define IA64_DCR_DD	(__IA64_UL(1) << IA64_DCR_DD_BIT)
+
+/* Interrupt Status Register */
+#define IA64_ISR_X_BIT		32	/* execute access */
+#define IA64_ISR_W_BIT		33	/* write access */
+#define IA64_ISR_R_BIT		34	/* read access */
+#define IA64_ISR_NA_BIT		35	/* non-access */
+#define IA64_ISR_SP_BIT		36	/* speculative load exception */
+#define IA64_ISR_RS_BIT		37	/* mandatory register-stack exception */
+#define IA64_ISR_IR_BIT		38	/* invalid register frame exception */
+#define IA64_ISR_CODE_MASK	0xf
+
+#define IA64_ISR_X	(__IA64_UL(1) << IA64_ISR_X_BIT)
+#define IA64_ISR_W	(__IA64_UL(1) << IA64_ISR_W_BIT)
+#define IA64_ISR_R	(__IA64_UL(1) << IA64_ISR_R_BIT)
+#define IA64_ISR_NA	(__IA64_UL(1) << IA64_ISR_NA_BIT)
+#define IA64_ISR_SP	(__IA64_UL(1) << IA64_ISR_SP_BIT)
+#define IA64_ISR_RS	(__IA64_UL(1) << IA64_ISR_RS_BIT)
+#define IA64_ISR_IR	(__IA64_UL(1) << IA64_ISR_IR_BIT)
+
+/* ISR code field for non-access instructions */
+#define IA64_ISR_CODE_TPA	0
+#define IA64_ISR_CODE_FC	1
+#define IA64_ISR_CODE_PROBE	2
+#define IA64_ISR_CODE_TAK	3
+#define IA64_ISR_CODE_LFETCH	4
+#define IA64_ISR_CODE_PROBEF	5
+
+#endif /* _ASM_IA64_KREGS_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/machvec.h linux-2.4.20-pre7/include/asm-ia64/machvec.h
--- linux-2.4.20-pre6/include/asm-ia64/machvec.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/machvec.h	Thu Sep 12 20:01:49 2002
@@ -18,11 +18,13 @@
 struct pt_regs;
 struct scatterlist;
 struct irq_desc;
+struct page;
 
 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 void ia64_mv_pci_enable_device_t (struct pci_dev *);
 typedef unsigned long ia64_mv_map_nr_t (unsigned long);
 typedef void ia64_mv_mca_init_t (void);
 typedef void ia64_mv_mca_handler_t (void);
@@ -45,6 +47,8 @@
 typedef void ia64_mv_pci_dma_sync_single (struct pci_dev *, dma_addr_t, size_t, int);
 typedef void ia64_mv_pci_dma_sync_sg (struct pci_dev *, struct scatterlist *, int, int);
 typedef unsigned long ia64_mv_pci_dma_address (struct scatterlist *);
+typedef int ia64_mv_pci_dma_supported (struct pci_dev *, u64);
+
 /*
  * WARNING: The legacy I/O space is _architected_.  Platforms are
  * expected to follow this architected model (see Section 10.7 in the
@@ -67,6 +71,8 @@
 #  include <asm/machvec_hpsim.h>
 # elif defined (CONFIG_IA64_DIG)
 #  include <asm/machvec_dig.h>
+# elif defined (CONFIG_IA64_HP_ZX1)
+#  include <asm/machvec_hpzx1.h>
 # elif defined (CONFIG_IA64_SGI_SN1)
 #  include <asm/machvec_sn1.h>
 # elif defined (CONFIG_IA64_SGI_SN2)
@@ -86,7 +92,8 @@
 #  define platform_cmci_handler	ia64_mv.cmci_handler
 #  define platform_log_print	ia64_mv.log_print
 #  define platform_pci_fixup	ia64_mv.pci_fixup
-#  define platform_send_ipi	ia64_mv.send_ipi
+#  define platform_pci_enable_device	ia64_mv.pci_enable_device
+#  define platform_send_ipi		ia64_mv.send_ipi
 #  define platform_global_tlb_purge	ia64_mv.global_tlb_purge
 #  define platform_pci_dma_init		ia64_mv.dma_init
 #  define platform_pci_alloc_consistent	ia64_mv.alloc_consistent
@@ -98,6 +105,7 @@
 #  define platform_pci_dma_sync_single	ia64_mv.sync_single
 #  define platform_pci_dma_sync_sg	ia64_mv.sync_sg
 #  define platform_pci_dma_address	ia64_mv.dma_address
+#  define platform_pci_dma_supported	ia64_mv.dma_supported
 #  define platform_irq_desc		ia64_mv.irq_desc
 #  define platform_irq_to_vector	ia64_mv.irq_to_vector
 #  define platform_local_vector_to_irq	ia64_mv.local_vector_to_irq
@@ -115,12 +123,14 @@
 	ia64_mv_cpu_init_t *cpu_init;
 	ia64_mv_irq_init_t *irq_init;
 	ia64_mv_pci_fixup_t *pci_fixup;
+	ia64_mv_pci_enable_device_t *pci_enable_device;
 	ia64_mv_map_nr_t *map_nr;
 	ia64_mv_mca_init_t *mca_init;
 	ia64_mv_mca_handler_t *mca_handler;
 	ia64_mv_cmci_handler_t *cmci_handler;
 	ia64_mv_log_print_t *log_print;
 	ia64_mv_send_ipi_t *send_ipi;
+	ia64_mv_global_tlb_purge_t *global_tlb_purge;
 	ia64_mv_pci_dma_init *dma_init;
 	ia64_mv_pci_alloc_consistent *alloc_consistent;
 	ia64_mv_pci_free_consistent *free_consistent;
@@ -131,6 +141,7 @@
 	ia64_mv_pci_dma_sync_single *sync_single;
 	ia64_mv_pci_dma_sync_sg *sync_sg;
 	ia64_mv_pci_dma_address *dma_address;
+	ia64_mv_pci_dma_supported *dma_supported;
 	ia64_mv_irq_desc *irq_desc;
 	ia64_mv_irq_to_vector *irq_to_vector;
 	ia64_mv_local_vector_to_irq *local_vector_to_irq;
@@ -146,8 +157,10 @@
 {						\
 	#name,					\
 	platform_setup,				\
+	platform_cpu_init,			\
 	platform_irq_init,			\
 	platform_pci_fixup,			\
+	platform_pci_enable_device,		\
 	platform_map_nr,			\
 	platform_mca_init,			\
 	platform_mca_handler,			\
@@ -165,6 +178,7 @@
 	platform_pci_dma_sync_single,		\
 	platform_pci_dma_sync_sg,		\
 	platform_pci_dma_address,		\
+	platform_pci_dma_supported,		\
 	platform_irq_desc,			\
 	platform_irq_to_vector,			\
 	platform_local_vector_to_irq,		\
@@ -196,6 +210,7 @@
 extern ia64_mv_pci_dma_sync_single swiotlb_sync_single;
 extern ia64_mv_pci_dma_sync_sg swiotlb_sync_sg;
 extern ia64_mv_pci_dma_address swiotlb_dma_address;
+extern ia64_mv_pci_dma_supported swiotlb_pci_dma_supported;
 
 /*
  * Define default versions so we can extend machvec for new platforms without having
@@ -225,6 +240,9 @@
 #ifndef platform_pci_fixup
 # define platform_pci_fixup	((ia64_mv_pci_fixup_t *) machvec_noop)
 #endif
+#ifndef platform_pci_enable_device
+# define platform_pci_enable_device	((ia64_mv_pci_enable_device_t *) machvec_noop)
+#endif
 #ifndef platform_send_ipi
 # define platform_send_ipi	ia64_send_ipi	/* default to architected version */
 #endif
@@ -261,6 +279,9 @@
 #ifndef platform_pci_dma_address
 # define  platform_pci_dma_address	swiotlb_dma_address
 #endif
+#ifndef platform_pci_dma_supported
+# define  platform_pci_dma_supported	swiotlb_pci_dma_supported
+#endif
 #ifndef platform_irq_desc
 # define platform_irq_desc		__ia64_irq_desc
 #endif
diff -urN linux-2.4.20-pre6/include/asm-ia64/machvec_hpzx1.h linux-2.4.20-pre7/include/asm-ia64/machvec_hpzx1.h
--- linux-2.4.20-pre6/include/asm-ia64/machvec_hpzx1.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-ia64/machvec_hpzx1.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,41 @@
+#ifndef _ASM_IA64_MACHVEC_HPZX1_h
+#define _ASM_IA64_MACHVEC_HPZX1_h
+
+extern ia64_mv_setup_t dig_setup;
+extern ia64_mv_pci_fixup_t hpzx1_pci_fixup;
+extern ia64_mv_pci_enable_device_t sba_enable_device;
+extern ia64_mv_map_nr_t map_nr_dense;
+extern ia64_mv_pci_alloc_consistent sba_alloc_consistent;
+extern ia64_mv_pci_free_consistent sba_free_consistent;
+extern ia64_mv_pci_map_single sba_map_single;
+extern ia64_mv_pci_unmap_single sba_unmap_single;
+extern ia64_mv_pci_map_sg sba_map_sg;
+extern ia64_mv_pci_unmap_sg sba_unmap_sg;
+extern ia64_mv_pci_dma_address sba_dma_address;
+extern ia64_mv_pci_dma_supported sba_dma_supported;
+
+/*
+ * 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			"hpzx1"
+#define platform_setup			dig_setup
+#define platform_pci_fixup		hpzx1_pci_fixup
+#define platform_pci_enable_device	sba_enable_device
+#define platform_map_nr			map_nr_dense
+#define platform_pci_dma_init		((ia64_mv_pci_dma_init *) machvec_noop)
+#define platform_pci_alloc_consistent	sba_alloc_consistent
+#define platform_pci_free_consistent	sba_free_consistent
+#define platform_pci_map_single		sba_map_single
+#define platform_pci_unmap_single	sba_unmap_single
+#define platform_pci_map_sg		sba_map_sg
+#define platform_pci_unmap_sg		sba_unmap_sg
+#define platform_pci_dma_sync_single	((ia64_mv_pci_dma_sync_single *) machvec_noop)
+#define platform_pci_dma_sync_sg	((ia64_mv_pci_dma_sync_sg *) machvec_noop)
+#define platform_pci_dma_address	sba_dma_address
+#define platform_pci_dma_supported	sba_dma_supported
+
+#endif /* _ASM_IA64_MACHVEC_HPZX1_h */
diff -urN linux-2.4.20-pre6/include/asm-ia64/machvec_init.h linux-2.4.20-pre7/include/asm-ia64/machvec_init.h
--- linux-2.4.20-pre6/include/asm-ia64/machvec_init.h	Thu Jan  4 12:50:17 2001
+++ linux-2.4.20-pre7/include/asm-ia64/machvec_init.h	Thu Sep 12 20:01:49 2002
@@ -5,6 +5,11 @@
 #include <asm/machvec.h>
 
 extern ia64_mv_send_ipi_t ia64_send_ipi;
+extern ia64_mv_global_tlb_purge_t ia64_global_tlb_purge;
+extern ia64_mv_irq_desc __ia64_irq_desc;
+extern ia64_mv_irq_to_vector __ia64_irq_to_vector;
+extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq;
+
 extern ia64_mv_inb_t __ia64_inb;
 extern ia64_mv_inw_t __ia64_inw;
 extern ia64_mv_inl_t __ia64_inl;
diff -urN linux-2.4.20-pre6/include/asm-ia64/machvec_sn1.h linux-2.4.20-pre7/include/asm-ia64/machvec_sn1.h
--- linux-2.4.20-pre6/include/asm-ia64/machvec_sn1.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/machvec_sn1.h	Thu Sep 12 20:01:49 2002
@@ -59,6 +59,7 @@
 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;
+extern ia64_mv_pci_dma_supported	sn_pci_dma_supported;
 
 /*
  * This stuff has dual use!
@@ -95,5 +96,6 @@
 #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
+#define platform_pci_dma_supported	sn_pci_dma_supported
 
 #endif /* _ASM_IA64_MACHVEC_SN1_h */
diff -urN linux-2.4.20-pre6/include/asm-ia64/machvec_sn2.h linux-2.4.20-pre7/include/asm-ia64/machvec_sn2.h
--- linux-2.4.20-pre6/include/asm-ia64/machvec_sn2.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/machvec_sn2.h	Thu Sep 12 20:01:49 2002
@@ -59,6 +59,7 @@
 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;
+extern ia64_mv_pci_dma_supported	sn_pci_dma_supported;
 
 /*
  * This stuff has dual use!
@@ -95,5 +96,6 @@
 #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
+#define platform_pci_dma_supported	sn_pci_dma_supported
 
 #endif /* _ASM_IA64_MACHVEC_SN2_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/module.h linux-2.4.20-pre7/include/asm-ia64/module.h
--- linux-2.4.20-pre6/include/asm-ia64/module.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/asm-ia64/module.h	Thu Sep 12 20:01:49 2002
@@ -51,6 +51,9 @@
 		return 0;
 	archdata = (struct archdata *)(mod->archdata_start);
 
+	if (archdata->unw_start == 0)
+		return 0;
+
 	/*
 	 * Make sure the unwind pointers are sane.
 	 */
diff -urN linux-2.4.20-pre6/include/asm-ia64/offsets.h linux-2.4.20-pre7/include/asm-ia64/offsets.h
--- linux-2.4.20-pre6/include/asm-ia64/offsets.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/offsets.h	Thu Sep 12 20:01:49 2002
@@ -8,7 +8,7 @@
  */
 #define PT_PTRACED_BIT		0
 #define PT_TRACESYS_BIT		1
-#define IA64_TASK_SIZE			3936	/* 0xf60 */
+#define IA64_TASK_SIZE			3424	/* 0xd60 */
 #define IA64_PT_REGS_SIZE		400	/* 0x190 */
 #define IA64_SWITCH_STACK_SIZE		560	/* 0x230 */
 #define IA64_SIGINFO_SIZE		128	/* 0x80 */
@@ -20,9 +20,9 @@
 #define IA64_TASK_SIGPENDING_OFFSET	16	/* 0x10 */
 #define IA64_TASK_NEED_RESCHED_OFFSET	40	/* 0x28 */
 #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_THREAD_OFFSET		992	/* 0x3e0 */
+#define IA64_TASK_THREAD_KSP_OFFSET	992	/* 0x3e0 */
+#define IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET 1616	/* 0x650 */
 #define IA64_TASK_PID_OFFSET		228	/* 0xe4 */
 #define IA64_TASK_MM_OFFSET		88	/* 0x58 */
 #define IA64_PT_REGS_CR_IPSR_OFFSET	0	/* 0x0 */
@@ -115,6 +115,7 @@
 #define IA64_SWITCH_STACK_AR_RNAT_OFFSET 536	/* 0x218 */
 #define IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET 544	/* 0x220 */
 #define IA64_SWITCH_STACK_PR_OFFSET	552	/* 0x228 */
+#define IA64_SIGCONTEXT_IP_OFFSET	40	/* 0x28 */
 #define IA64_SIGCONTEXT_AR_BSP_OFFSET	72	/* 0x48 */
 #define IA64_SIGCONTEXT_AR_FPSR_OFFSET	104	/* 0x68 */
 #define IA64_SIGCONTEXT_AR_RNAT_OFFSET	80	/* 0x50 */
diff -urN linux-2.4.20-pre6/include/asm-ia64/page.h linux-2.4.20-pre7/include/asm-ia64/page.h
--- linux-2.4.20-pre6/include/asm-ia64/page.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/page.h	Thu Sep 12 20:01:49 2002
@@ -55,7 +55,7 @@
 #ifdef CONFIG_IA64_GENERIC
 # include <asm/machvec.h>
 # define virt_to_page(kaddr)	(mem_map + platform_map_nr(kaddr))
-# define page_to_phys(page)	XXX fix me
+# define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
 #elif defined (CONFIG_IA64_SGI_SN1)
 # ifndef CONFIG_DISCONTIGMEM
 #  define virt_to_page(kaddr)	(mem_map + MAP_NR_DENSE(kaddr))
@@ -65,7 +65,13 @@
 # define virt_to_page(kaddr)	(mem_map + MAP_NR_DENSE(kaddr))
 # define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
 #endif
-#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+  struct page;
+  extern int ia64_page_valid (struct page *);
+# define VALID_PAGE(page)	(((page - mem_map) < max_mapnr) && ia64_page_valid(page))
+#else
+# define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#endif
 
 typedef union ia64_va {
 	struct {
diff -urN linux-2.4.20-pre6/include/asm-ia64/pci.h linux-2.4.20-pre7/include/asm-ia64/pci.h
--- linux-2.4.20-pre6/include/asm-ia64/pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/pci.h	Thu Sep 12 20:01:49 2002
@@ -19,6 +19,11 @@
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
+void pcibios_config_init(void);
+struct pci_bus *pcibios_scan_root(void *acpi_handle, int segment, int bus);
+extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
+extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
+
 struct pci_dev;
 
 static inline void
@@ -45,6 +50,7 @@
 #define pci_dma_sync_single		platform_pci_dma_sync_single
 #define pci_dma_sync_sg			platform_pci_dma_sync_sg
 #define sg_dma_address			platform_pci_dma_address
+#define pci_dma_supported		platform_pci_dma_supported
 
 /* pci_unmap_{single,page} is not a nop, thus... */
 #define DECLARE_PCI_UNMAP_ADDR(addr_name)	dma_addr_t addr_name;
@@ -54,17 +60,6 @@
 #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
- * 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.
- */
-static inline int
-pci_dma_supported (struct pci_dev *hwdev, u64 mask)
-{
-	return 1;
-}
-
 #define pci_map_page(dev,pg,off,size,dir)				\
 	pci_map_single((dev), page_address(pg) + (off), (size), (dir))
 #define pci_unmap_page(dev,dma_addr,size,dir)				\
@@ -73,7 +68,7 @@
 /* The ia64 platform always supports 64-bit addressing. */
 #define pci_dac_dma_supported(pci_dev, mask)	(1)
 
-#define pci_dac_page_to_dma(dev,pg,off,dir)	((dma64_addr_t) page_to_bus(pg) + (off))
+#define pci_dac_page_to_dma(dev,pg,off,dir)	((dma_addr_t) page_to_bus(pg) + (off))
 #define pci_dac_dma_to_page(dev,dma_addr)	(virt_to_page(bus_to_virt(dma_addr)))
 #define pci_dac_dma_to_offset(dev,dma_addr)	((dma_addr) & ~PAGE_MASK)
 #define pci_dac_dma_sync_single(dev,dma_addr,len,dir)	do { /* nothing */ } while (0)
@@ -87,4 +82,17 @@
 extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
 				enum pci_mmap_state mmap_state, int write_combine);
 
+struct pci_controller {
+	void *acpi_handle;
+	void *iommu;
+	int segment;
+
+	u64 mem_offset;
+
+	void *platform_data;
+};
+
+#define PCI_CONTROLLER(dev) ((struct pci_controller *) dev->sysdata)
+#define PCI_SEGMENT(dev)    (PCI_CONTROLLER(dev)->segment)
+
 #endif /* _ASM_IA64_PCI_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/perfmon.h linux-2.4.20-pre7/include/asm-ia64/perfmon.h
--- linux-2.4.20-pre6/include/asm-ia64/perfmon.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/perfmon.h	Thu Sep 12 20:01:49 2002
@@ -23,6 +23,7 @@
 #define PFM_GET_FEATURES	0x0c
 #define PFM_DEBUG		0x0d
 #define PFM_UNPROTECT_CONTEXT	0x0e
+#define PFM_GET_PMC_RESET_VAL	0x0f
 
 
 /*
@@ -171,6 +172,7 @@
 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);
+extern void perfmon_init_percpu(void);
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.20-pre6/include/asm-ia64/pgalloc.h linux-2.4.20-pre7/include/asm-ia64/pgalloc.h
--- linux-2.4.20-pre6/include/asm-ia64/pgalloc.h	Fri Nov  9 14:26:17 2001
+++ linux-2.4.20-pre7/include/asm-ia64/pgalloc.h	Thu Sep 12 20:01:49 2002
@@ -8,13 +8,14 @@
  * 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>
  * Copyright (C) 2000, Goutham Rao <goutham.rao@intel.com>
  */
 
 #include <linux/config.h>
 
+#include <linux/compiler.h>
 #include <linux/mm.h>
 #include <linux/threads.h>
 
@@ -194,6 +195,8 @@
 #else
 	if (vma->vm_mm == current->active_mm)
 		asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(PAGE_SHIFT << 2) : "memory");
+	else
+		vma->vm_mm->context = 0;
 #endif
 }
 
@@ -204,30 +207,41 @@
 static inline void
 flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end)
 {
-	if (rgn_index(start) != rgn_index(end))
-		printk("flush_tlb_pgtables: can't flush across regions!!\n");
-	flush_tlb_range(mm, ia64_thash(start), ia64_thash(end));
+	if (unlikely(end - start >= 1024*1024*1024*1024UL
+		     || rgn_index(start) != rgn_index(end - 1)))
+		/*
+		 * This condition is very rare and normal applications shouldn't get
+		 * here. No attempt has been made to optimize for this case.
+		 */
+		flush_tlb_all();
+	else
+		flush_tlb_range(mm, ia64_thash(start), ia64_thash(end));
 }
 
 /*
- * Now for some cache flushing routines.  This is the kind of stuff
- * that can be very expensive, so try to avoid them whenever possible.
+ * Cache flushing routines.  This is the kind of stuff that can be very expensive, so try
+ * to avoid them whenever possible.
  */
 
-/* Caches aren't brain-dead on the IA-64. */
 #define flush_cache_all()			do { } while (0)
 #define flush_cache_mm(mm)			do { } while (0)
 #define flush_cache_range(mm, start, end)	do { } while (0)
 #define flush_cache_page(vma, vmaddr)		do { } while (0)
 #define flush_page_to_ram(page)			do { } while (0)
+#define flush_icache_page(vma,page)		do { } while (0)
+
+#define flush_dcache_page(page)			\
+do {						\
+	clear_bit(PG_arch_1, &(page)->flags);	\
+} while (0)
 
 extern void flush_icache_range (unsigned long start, unsigned long end);
 
-static inline void
-flush_dcache_page (struct page *page)
-{
-	clear_bit(PG_arch_1, &page->flags);
-}
+#define flush_icache_user_range(vma, page, user_addr, len)					\
+do {												\
+	unsigned long _addr = (unsigned long) page_address(page) + ((user_addr) & ~PAGE_MASK);	\
+	flush_icache_range(_addr, _addr + (len));						\
+} while (0)
 
 static inline void
 clear_user_page (void *addr, unsigned long vaddr, struct page *page)
diff -urN linux-2.4.20-pre6/include/asm-ia64/pgtable.h linux-2.4.20-pre7/include/asm-ia64/pgtable.h
--- linux-2.4.20-pre6/include/asm-ia64/pgtable.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/pgtable.h	Thu Sep 12 20:01:49 2002
@@ -156,12 +156,6 @@
 #define pte_ERROR(e)	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
 
 
-/*
- * Some definitions to translate between mem_map, PTEs, and page
- * addresses:
- */
-
-
 /* Quick test to see if ADDR is a (potentially) valid physical address. */
 static inline long
 ia64_phys_addr_valid (unsigned long addr)
@@ -204,7 +198,13 @@
 
 #define VMALLOC_START		(0xa000000000000000 + 3*PAGE_SIZE)
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
-#define VMALLOC_END		(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+# define VMALLOC_END_INIT        (0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9))) 
+# define VMALLOC_END             vmalloc_end
+  extern unsigned long vmalloc_end;
+#else
+# define VMALLOC_END		(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+#endif
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -448,6 +448,20 @@
  */
 #define pgtable_cache_init()	do { } while (0)
 
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+
+/* arch mem_map init routines are needed due to holes in a virtual mem_map */
+#define HAVE_ARCH_MEMMAP_INIT
+
+typedef unsigned long memmap_init_callback_t(struct page *start,
+	struct page *end, int zone, unsigned long start_paddr, int highmem);
+
+extern unsigned long arch_memmap_init (memmap_init_callback_t *callback,
+	struct page *start, struct page *end, int zone,
+	unsigned long start_paddr, int highmem);
+
+#endif /* CONFIG_VIRTUAL_MEM_MAP */
+
 # endif /* !__ASSEMBLY__ */
 
 /*
@@ -468,9 +482,4 @@
 #define KERNEL_TR_PAGE_SIZE	(1 << KERNEL_TR_PAGE_SHIFT)
 #define KERNEL_TR_PAGE_NUM	((KERNEL_START - PAGE_OFFSET) / KERNEL_TR_PAGE_SIZE)
 
-/*
- * No page table caches to initialise
- */
-#define pgtable_cache_init()	do { } while (0)
-
 #endif /* _ASM_IA64_PGTABLE_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/processor.h linux-2.4.20-pre7/include/asm-ia64/processor.h
--- linux-2.4.20-pre6/include/asm-ia64/processor.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/processor.h	Thu Sep 12 20:01:49 2002
@@ -18,7 +18,6 @@
 
 #include <asm/ptrace.h>
 #include <asm/kregs.h>
-#include <asm/system.h>
 #include <asm/types.h>
 
 #define IA64_NUM_DBG_REGS	8
@@ -54,114 +53,6 @@
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/* Processor status register bits: */
-#define IA64_PSR_BE_BIT		1
-#define IA64_PSR_UP_BIT		2
-#define IA64_PSR_AC_BIT		3
-#define IA64_PSR_MFL_BIT	4
-#define IA64_PSR_MFH_BIT	5
-#define IA64_PSR_IC_BIT		13
-#define IA64_PSR_I_BIT		14
-#define IA64_PSR_PK_BIT		15
-#define IA64_PSR_DT_BIT		17
-#define IA64_PSR_DFL_BIT	18
-#define IA64_PSR_DFH_BIT	19
-#define IA64_PSR_SP_BIT		20
-#define IA64_PSR_PP_BIT		21
-#define IA64_PSR_DI_BIT		22
-#define IA64_PSR_SI_BIT		23
-#define IA64_PSR_DB_BIT		24
-#define IA64_PSR_LP_BIT		25
-#define IA64_PSR_TB_BIT		26
-#define IA64_PSR_RT_BIT		27
-/* The following are not affected by save_flags()/restore_flags(): */
-#define IA64_PSR_CPL0_BIT	32
-#define IA64_PSR_CPL1_BIT	33
-#define IA64_PSR_IS_BIT		34
-#define IA64_PSR_MC_BIT		35
-#define IA64_PSR_IT_BIT		36
-#define IA64_PSR_ID_BIT		37
-#define IA64_PSR_DA_BIT		38
-#define IA64_PSR_DD_BIT		39
-#define IA64_PSR_SS_BIT		40
-#define IA64_PSR_RI_BIT		41
-#define IA64_PSR_ED_BIT		43
-#define IA64_PSR_BN_BIT		44
-
-#define IA64_PSR_BE	(__IA64_UL(1) << IA64_PSR_BE_BIT)
-#define IA64_PSR_UP	(__IA64_UL(1) << IA64_PSR_UP_BIT)
-#define IA64_PSR_AC	(__IA64_UL(1) << IA64_PSR_AC_BIT)
-#define IA64_PSR_MFL	(__IA64_UL(1) << IA64_PSR_MFL_BIT)
-#define IA64_PSR_MFH	(__IA64_UL(1) << IA64_PSR_MFH_BIT)
-#define IA64_PSR_IC	(__IA64_UL(1) << IA64_PSR_IC_BIT)
-#define IA64_PSR_I	(__IA64_UL(1) << IA64_PSR_I_BIT)
-#define IA64_PSR_PK	(__IA64_UL(1) << IA64_PSR_PK_BIT)
-#define IA64_PSR_DT	(__IA64_UL(1) << IA64_PSR_DT_BIT)
-#define IA64_PSR_DFL	(__IA64_UL(1) << IA64_PSR_DFL_BIT)
-#define IA64_PSR_DFH	(__IA64_UL(1) << IA64_PSR_DFH_BIT)
-#define IA64_PSR_SP	(__IA64_UL(1) << IA64_PSR_SP_BIT)
-#define IA64_PSR_PP	(__IA64_UL(1) << IA64_PSR_PP_BIT)
-#define IA64_PSR_DI	(__IA64_UL(1) << IA64_PSR_DI_BIT)
-#define IA64_PSR_SI	(__IA64_UL(1) << IA64_PSR_SI_BIT)
-#define IA64_PSR_DB	(__IA64_UL(1) << IA64_PSR_DB_BIT)
-#define IA64_PSR_LP	(__IA64_UL(1) << IA64_PSR_LP_BIT)
-#define IA64_PSR_TB	(__IA64_UL(1) << IA64_PSR_TB_BIT)
-#define IA64_PSR_RT	(__IA64_UL(1) << IA64_PSR_RT_BIT)
-/* The following are not affected by save_flags()/restore_flags(): */
-#define IA64_PSR_IS	(__IA64_UL(1) << IA64_PSR_IS_BIT)
-#define IA64_PSR_MC	(__IA64_UL(1) << IA64_PSR_MC_BIT)
-#define IA64_PSR_IT	(__IA64_UL(1) << IA64_PSR_IT_BIT)
-#define IA64_PSR_ID	(__IA64_UL(1) << IA64_PSR_ID_BIT)
-#define IA64_PSR_DA	(__IA64_UL(1) << IA64_PSR_DA_BIT)
-#define IA64_PSR_DD	(__IA64_UL(1) << IA64_PSR_DD_BIT)
-#define IA64_PSR_SS	(__IA64_UL(1) << IA64_PSR_SS_BIT)
-#define IA64_PSR_RI	(__IA64_UL(3) << IA64_PSR_RI_BIT)
-#define IA64_PSR_ED	(__IA64_UL(1) << IA64_PSR_ED_BIT)
-#define IA64_PSR_BN	(__IA64_UL(1) << IA64_PSR_BN_BIT)
-
-/* User mask bits: */
-#define IA64_PSR_UM	(IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC | IA64_PSR_MFL | IA64_PSR_MFH)
-
-/* Default Control Register */
-#define IA64_DCR_PP_BIT		 0	/* privileged performance monitor default */
-#define IA64_DCR_BE_BIT		 1	/* big-endian default */
-#define IA64_DCR_LC_BIT		 2	/* ia32 lock-check enable */
-#define IA64_DCR_DM_BIT		 8	/* defer TLB miss faults */
-#define IA64_DCR_DP_BIT		 9	/* defer page-not-present faults */
-#define IA64_DCR_DK_BIT		10	/* defer key miss faults */
-#define IA64_DCR_DX_BIT		11	/* defer key permission faults */
-#define IA64_DCR_DR_BIT		12	/* defer access right faults */
-#define IA64_DCR_DA_BIT		13	/* defer access bit faults */
-#define IA64_DCR_DD_BIT		14	/* defer debug faults */
-
-#define IA64_DCR_PP	(__IA64_UL(1) << IA64_DCR_PP_BIT)
-#define IA64_DCR_BE	(__IA64_UL(1) << IA64_DCR_BE_BIT)
-#define IA64_DCR_LC	(__IA64_UL(1) << IA64_DCR_LC_BIT)
-#define IA64_DCR_DM	(__IA64_UL(1) << IA64_DCR_DM_BIT)
-#define IA64_DCR_DP	(__IA64_UL(1) << IA64_DCR_DP_BIT)
-#define IA64_DCR_DK	(__IA64_UL(1) << IA64_DCR_DK_BIT)
-#define IA64_DCR_DX	(__IA64_UL(1) << IA64_DCR_DX_BIT)
-#define IA64_DCR_DR	(__IA64_UL(1) << IA64_DCR_DR_BIT)
-#define IA64_DCR_DA	(__IA64_UL(1) << IA64_DCR_DA_BIT)
-#define IA64_DCR_DD	(__IA64_UL(1) << IA64_DCR_DD_BIT)
-
-/* Interrupt Status Register */
-#define IA64_ISR_X_BIT		32	/* execute access */
-#define IA64_ISR_W_BIT		33	/* write access */
-#define IA64_ISR_R_BIT		34	/* read access */
-#define IA64_ISR_NA_BIT		35	/* non-access */
-#define IA64_ISR_SP_BIT		36	/* speculative load exception */
-#define IA64_ISR_RS_BIT		37	/* mandatory register-stack exception */
-#define IA64_ISR_IR_BIT		38	/* invalid register frame exception */
-
-#define IA64_ISR_X	(__IA64_UL(1) << IA64_ISR_X_BIT)
-#define IA64_ISR_W	(__IA64_UL(1) << IA64_ISR_W_BIT)
-#define IA64_ISR_R	(__IA64_UL(1) << IA64_ISR_R_BIT)
-#define IA64_ISR_NA	(__IA64_UL(1) << IA64_ISR_NA_BIT)
-#define IA64_ISR_SP	(__IA64_UL(1) << IA64_ISR_SP_BIT)
-#define IA64_ISR_RS	(__IA64_UL(1) << IA64_ISR_RS_BIT)
-#define IA64_ISR_IR	(__IA64_UL(1) << IA64_ISR_IR_BIT)
-
 #define IA64_THREAD_FPH_VALID	(__IA64_UL(1) << 0)	/* floating-point high state valid? */
 #define IA64_THREAD_DBG_VALID	(__IA64_UL(1) << 1)	/* debug registers valid? */
 #define IA64_THREAD_PM_VALID	(__IA64_UL(1) << 2)	/* performance registers valid? */
@@ -188,6 +79,7 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/threads.h>
+#include <linux/cache.h>
 
 #include <asm/fpu.h>
 #include <asm/offsets.h>
@@ -281,10 +173,18 @@
 	__u64 ipi_count;
 	__u64 prof_counter;
 	__u64 prof_multiplier;
+# ifdef CONFIG_PERFMON
 	__u32 pfm_syst_wide;
 	__u32 pfm_dcr_pp;
-	/* this is written to by *other* CPUs: */
-	__u64 ipi_operation ____cacheline_aligned;
+# endif
+	union {
+		/*
+		 *  This is written to by *other* CPUs,
+		 *  so isolate it in its own cacheline.
+		 */
+		__u64 operation;
+		char pad[SMP_CACHE_BYTES] ____cacheline_aligned;
+	} ipi;
 #endif
 #ifdef CONFIG_NUMA
 	void *node_directory;
@@ -293,7 +193,7 @@
 #endif
 	/* Platform specific word.  MUST BE LAST IN STRUCT */
 	__u64 platform_specific;
-} __attribute__ ((aligned (PAGE_SIZE))) ;
+} __attribute__ ((aligned (PAGE_SIZE)));
 
 /*
  * The "local" data pointer.  It points to the per-CPU data of the currently executing
@@ -388,6 +288,7 @@
 	__u64 dbr[IA64_NUM_DBG_REGS];
 	__u64 ibr[IA64_NUM_DBG_REGS];
 	struct ia64_fpreg fph[96];	/* saved/loaded on demand */
+	int last_fph_cpu;
 };
 
 #define INIT_THREAD {					\
@@ -405,12 +306,8 @@
 
 #define start_thread(regs,new_ip,new_sp) do {							\
 	set_fs(USER_DS);									\
-	ia64_psr(regs)->dfh = 1;	/* disable fph */					\
-	ia64_psr(regs)->mfh = 0;	/* clear mfh */						\
-	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_ipsr = ((regs->cr_ipsr | (IA64_PSR_BITS_TO_SET | IA64_PSR_CPL | IA64_PSR_SP))	\
+			 & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS));		\
 	regs->cr_iip = new_ip;									\
 	regs->ar_rsc = 0xf;		/* eager mode, privilege level 3 */			\
 	regs->ar_rnat = 0;									\
@@ -528,8 +425,6 @@
 	}
 }
 
-#ifndef CONFIG_SMP
-
 static inline struct task_struct *
 ia64_get_fpu_owner (void)
 {
@@ -542,8 +437,6 @@
 	ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) t);
 }
 
-#endif /* !CONFIG_SMP */
-
 extern void __ia64_init_fpu (void);
 extern void __ia64_save_fpu (struct ia64_fpreg *fph);
 extern void __ia64_load_fpu (struct ia64_fpreg *fph);
@@ -654,9 +547,22 @@
  * interrupt enable bits.  Don't trigger any mandatory RSE references while this bit is
  * off!
  */
-#define ia64_clear_ic(flags)						\
-	asm volatile ("mov %0=psr;; rsm psr.i | psr.ic;; srlz.i;;"	\
-			      : "=r"(flags) :: "memory");
+static inline __u64
+ia64_clear_ic (void)
+{
+	__u64 psr;
+	asm volatile ("mov %0=psr;; rsm psr.i | psr.ic;; srlz.i;;" : "=r"(psr) :: "memory");
+	return psr;
+}
+
+/*
+ * Restore the psr.
+ */
+static inline void
+ia64_set_psr (__u64 psr)
+{
+	asm volatile (";; mov psr.l=%0;; srlz.d" :: "r" (psr) : "memory");
+}
 
 /*
  * Insert a translation into an instruction and/or data translation
diff -urN linux-2.4.20-pre6/include/asm-ia64/sal.h linux-2.4.20-pre7/include/asm-ia64/sal.h
--- linux-2.4.20-pre6/include/asm-ia64/sal.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/sal.h	Thu Sep 12 20:01:49 2002
@@ -24,9 +24,9 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/efi.h>
 
 #include <asm/pal.h>
-#include <asm/efi.h>
 #include <asm/system.h>
 #include <asm/fpu.h>
 
@@ -241,32 +241,32 @@
 
 /* SAL Error Record Section GUID Definitions */
 #define SAL_PROC_DEV_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf1, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID ( 0xe429faf1, 0x3cb7, 0x11d4,  0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_MEM_DEV_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf2, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf2, 0x3cb7, 0x11d4,  0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_SEL_DEV_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf3, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf3, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_PCI_BUS_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf4, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf4, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf5, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf5, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_PCI_COMP_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf6, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf6, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_SPECIFIC_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf7, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf7, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_HOST_CTLR_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf8, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 #define SAL_PLAT_BUS_ERR_SECT_GUID  \
-    ((efi_guid_t) { 0xe429faf9, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
-                    0xc7, 0x3c, 0x88, 0x81 }} )
+    EFI_GUID(  0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+                    0xc7, 0x3c, 0x88, 0x81 )
 
 #define MAX_CACHE_ERRORS			6
 #define MAX_TLB_ERRORS				6
diff -urN linux-2.4.20-pre6/include/asm-ia64/serial.h linux-2.4.20-pre7/include/asm-ia64/serial.h
--- linux-2.4.20-pre6/include/asm-ia64/serial.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/serial.h	Thu Sep 12 20:01:49 2002
@@ -35,7 +35,9 @@
 #else
 #define RS_TABLE_SIZE
 #endif
-	
+
+#define MCA_COM_FLAGS  STD_COM_FLAGS
+
 /*
  * The following define the access methods for the HUB6 card. All
  * access is through two ports for all 24 possible chips. The card is
@@ -60,16 +62,16 @@
 	{ 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
+ * 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			\
+#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
+							   and you get to edit 
+							   boatloads of these 
 							   comments. Not worth
 							   it */
 
@@ -131,12 +133,12 @@
 
 #ifdef CONFIG_MCA
 #define MCA_SERIAL_PORT_DFNS			\
-	{ 0, BASE_BAUD, 0x3220, 3, STD_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x3228, 3, STD_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4220, 3, STD_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4228, 3, STD_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5220, 3, STD_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5228, 3, STD_COM_FLAGS },
+	{ 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS },	\
+	{ 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS },	\
+	{ 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS },	\
+	{ 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS },	\
+	{ 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS },	\
+	{ 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS },
 #else
 #define MCA_SERIAL_PORT_DFNS
 #endif
diff -urN linux-2.4.20-pre6/include/asm-ia64/siginfo.h linux-2.4.20-pre7/include/asm-ia64/siginfo.h
--- linux-2.4.20-pre6/include/asm-ia64/siginfo.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/siginfo.h	Thu Sep 12 20:01:49 2002
@@ -153,7 +153,8 @@
 #define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
 #define ILL_BADIADDR	(__SI_FAULT|9)	/* unimplemented instruction address */
 #define __ILL_BREAK	(__SI_FAULT|10)	/* illegal break */
-#define NSIGILL		10
+#define __ILL_BNDMOD	(__SI_FAULT|11)	/* bundle-update (modification) in progress */
+#define NSIGILL		11
 
 /*
  * SIGFPE si_codes
diff -urN linux-2.4.20-pre6/include/asm-ia64/sn/sn2/shub_md.h linux-2.4.20-pre7/include/asm-ia64/sn/sn2/shub_md.h
--- linux-2.4.20-pre6/include/asm-ia64/sn/sn2/shub_md.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/sn/sn2/shub_md.h	Thu Sep 12 20:01:49 2002
@@ -1,14 +1,12 @@
-/**************************************************************************
- *                                                                        *
- *  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.  *
- *                                                                        *
- **************************************************************************/
+/*
+ *
+ * This file is subject to 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 _SHUB_MD_H
 #define _SHUB_MD_H
diff -urN linux-2.4.20-pre6/include/asm-ia64/string.h linux-2.4.20-pre7/include/asm-ia64/string.h
--- linux-2.4.20-pre6/include/asm-ia64/string.h	Tue Jul 31 10:30:09 2001
+++ linux-2.4.20-pre7/include/asm-ia64/string.h	Thu Sep 12 20:01:49 2002
@@ -5,8 +5,8 @@
  * Here is where we want to put optimized versions of the string
  * routines.
  *
- * 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/config.h>	/* remove this once we remove the A-step workaround... */
@@ -17,7 +17,7 @@
 #define __HAVE_ARCH_BCOPY	1 /* see arch/ia64/lib/memcpy.S */
 
 extern __kernel_size_t strlen (const char *);
-extern void *memset (void *, int, __kernel_size_t);
 extern void *memcpy (void *, const void *, __kernel_size_t);
+extern void *memset (void *, int, __kernel_size_t);
 
 #endif /* _ASM_IA64_STRING_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/system.h linux-2.4.20-pre7/include/asm-ia64/system.h
--- linux-2.4.20-pre6/include/asm-ia64/system.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/system.h	Thu Sep 12 20:01:49 2002
@@ -14,18 +14,12 @@
  */
 #include <linux/config.h>
 
+#include <asm/kregs.h>
 #include <asm/page.h>
+#include <asm/pal.h>
 
 #define KERNEL_START		(PAGE_OFFSET + 68*1024*1024)
 
-/*
- * The following #defines must match with vmlinux.lds.S:
- */
-#define IVT_ADDR		(KERNEL_START)
-#define IVT_END_ADDR		(KERNEL_START + 0x8000)
-#define ZERO_PAGE_ADDR		PAGE_ALIGN(IVT_END_ADDR)
-#define SWAPPER_PGD_ADDR	(ZERO_PAGE_ADDR + 1*PAGE_SIZE)
-
 #define GATE_ADDR		(0xa000000000000000 + PAGE_SIZE)
 #define PERCPU_ADDR		(0xa000000000000000 + 2*PAGE_SIZE)
 
@@ -35,10 +29,11 @@
 #include <linux/types.h>
 
 struct pci_vector_struct {
+	__u16 segment;	/* PCI Segment number */
 	__u16 bus;	/* PCI Bus number */
 	__u32 pci_id;	/* ACPI split 16 bits device, 16 bits function (see section 6.1.1) */
 	__u8 pin;	/* PCI PIN (0 = A, 1 = B, 2 = C, 3 = D) */
-	__u8 irq;	/* IRQ assigned */
+	__u32 irq;	/* IRQ assigned */
 };
 
 extern struct ia64_boot_param {
@@ -109,6 +104,8 @@
 #define set_mb(var, value)	do { (var) = (value); mb(); } while (0)
 #define set_wmb(var, value)	do { (var) = (value); mb(); } while (0)
 
+#define safe_halt()         ia64_pal_halt(1)                /* PAL_HALT */
+
 /*
  * The group barrier in front of the rsm & ssm are necessary to ensure
  * that none of the previous instructions in the same group are
@@ -143,16 +140,21 @@
 	}										\
 } while (0)
 
-# define local_irq_restore(x)						 \
-do {									 \
-	unsigned long ip, old_psr, psr = (x);				 \
-									 \
-	__asm__ __volatile__ (";;mov %0=psr; mov psr.l=%1;; srlz.d"	 \
-			      : "=&r" (old_psr) : "r" (psr) : "memory"); \
-	if ((old_psr & (1UL << 14)) && !(psr & (1UL << 14))) {		 \
-		__asm__ ("mov %0=ip" : "=r"(ip));			 \
-		last_cli_ip = ip;					 \
-	}								 \
+# define local_irq_restore(x)							\
+do {										\
+	unsigned long ip, old_psr, psr = (x);					\
+										\
+	__asm__ __volatile__ ("mov %0=psr;"					\
+			      "cmp.ne p6,p7=%1,r0;;"				\
+			      "(p6) ssm psr.i;"					\
+			      "(p7) rsm psr.i;;"				\
+			      "srlz.d"						\
+			      : "=&r" (old_psr) : "r"((psr) & IA64_PSR_I)	\
+			      : "p6", "p7", "memory");				\
+	if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) {			\
+		__asm__ ("mov %0=ip" : "=r"(ip));				\
+		last_cli_ip = ip;						\
+	}									\
 } while (0)
 
 #else /* !CONFIG_IA64_DEBUG_IRQ */
@@ -161,8 +163,12 @@
 						      : "=r" (x) :: "memory")
 # define local_irq_disable()	__asm__ __volatile__ (";; rsm psr.i;;" ::: "memory")
 /* (potentially) setting psr.i requires data serialization: */
-# define local_irq_restore(x)	__asm__ __volatile__ (";; mov psr.l=%0;; srlz.d"	\
-						      :: "r" (x) : "memory")
+# define local_irq_restore(x)	__asm__ __volatile__ ("cmp.ne p6,p7=%0,r0;;"		\
+						      "(p6) ssm psr.i;"			\
+						      "(p7) rsm psr.i;;"		\
+						      "srlz.d"				\
+						      :: "r"((x) & IA64_PSR_I)		\
+						      : "p6", "p7", "memory")
 #endif /* !CONFIG_IA64_DEBUG_IRQ */
 
 #define local_irq_enable()	__asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory")
@@ -395,26 +401,39 @@
 } while (0)
 
 #ifdef CONFIG_SMP
-  /*
-   * In the SMP case, we save the fph state when context-switching
-   * away from a thread that modified fph.  This way, when the thread
-   * gets scheduled on another CPU, the CPU can pick up the state from
-   * task->thread.fph, avoiding the complication of having to fetch
-   * the latest fph state from another CPU.
-   */
-# define switch_to(prev,next,last) do {						\
-	if (ia64_psr(ia64_task_regs(prev))->mfh) {				\
-		ia64_psr(ia64_task_regs(prev))->mfh = 0;			\
-		(prev)->thread.flags |= IA64_THREAD_FPH_VALID;			\
-		__ia64_save_fpu((prev)->thread.fph);				\
-	}									\
-	ia64_psr(ia64_task_regs(prev))->dfh = 1;				\
-	__switch_to(prev,next,last);						\
+
+/* Return true if this CPU can call the console drivers in printk() */
+#define arch_consoles_callable() (cpu_online_map & (1UL << smp_processor_id()))
+
+/*
+ * In the SMP case, we save the fph state when context-switching
+ * away from a thread that modified fph.  This way, when the thread
+ * gets scheduled on another CPU, the CPU can pick up the state from
+ * task->thread.fph, avoiding the complication of having to fetch
+ * the latest fph state from another CPU.
+ */
+# define switch_to(prev,next,last) do {					\
+	if (ia64_psr(ia64_task_regs(prev))->mfh) {			\
+		ia64_psr(ia64_task_regs(prev))->mfh = 0;		\
+		(prev)->thread.flags |= IA64_THREAD_FPH_VALID;		\
+		__ia64_save_fpu((prev)->thread.fph);			\
+		(prev)->thread.last_fph_cpu = smp_processor_id();	\
+	}								\
+	if ((next)->thread.flags & IA64_THREAD_FPH_VALID) {		\
+		if (((next)->thread.last_fph_cpu == smp_processor_id()) \
+		    && (ia64_get_fpu_owner() == next)) {		\
+			ia64_psr(ia64_task_regs(next))->dfh = 0;	\
+			ia64_psr(ia64_task_regs(next))->mfh = 0;	\
+		} else {						\
+			ia64_psr(ia64_task_regs(next))->dfh = 1;	\
+		}							\
+	}								\
+	__switch_to(prev,next,last);					\
   } while (0)
 #else
-# define switch_to(prev,next,last) do {						\
+# define switch_to(prev,next,last) do {					\
 	ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next));	\
-	__switch_to(prev,next,last);						\
+	__switch_to(prev,next,last);					\
 } while (0)
 #endif
 
diff -urN linux-2.4.20-pre6/include/asm-ia64/uaccess.h linux-2.4.20-pre7/include/asm-ia64/uaccess.h
--- linux-2.4.20-pre6/include/asm-ia64/uaccess.h	Thu Apr  5 12:51:47 2001
+++ linux-2.4.20-pre7/include/asm-ia64/uaccess.h	Thu Sep 12 20:01:49 2002
@@ -320,4 +320,22 @@
 extern struct exception_fixup search_exception_table (unsigned long addr);
 extern void handle_exception (struct pt_regs *regs, struct exception_fixup fixup);
 
+#ifdef GAS_HAS_LOCAL_TAGS
+#define SEARCH_EXCEPTION_TABLE(regs) search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
+#else
+#define SEARCH_EXCEPTION_TABLE(regs) search_exception_table(regs->cr_iip);
+#endif
+
+static inline int
+done_with_exception (struct pt_regs *regs)
+{
+	struct exception_fixup fix;
+	fix = SEARCH_EXCEPTION_TABLE(regs);
+	if (fix.cont) {
+		handle_exception(regs, fix);
+		return 1;
+	}
+	return 0;
+}
+
 #endif /* _ASM_IA64_UACCESS_H */
diff -urN linux-2.4.20-pre6/include/asm-ia64/unistd.h linux-2.4.20-pre7/include/asm-ia64/unistd.h
--- linux-2.4.20-pre6/include/asm-ia64/unistd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ia64/unistd.h	Thu Sep 12 20:01:49 2002
@@ -206,7 +206,12 @@
 #define __NR_getdents64			1214
 #define __NR_getunwind			1215
 #define __NR_readahead			1216
+/*
+ * 1217-1228: reserved for xattr
+ * 1230-1232: reserved for futex and sched_[sg]etaffinity.
+ */
 #define __NR_tkill			1229
+#define __NR_security			1233 /* syscall for security modules */
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -urN linux-2.4.20-pre6/include/asm-ia64/vga.h linux-2.4.20-pre7/include/asm-ia64/vga.h
--- linux-2.4.20-pre6/include/asm-ia64/vga.h	Sun Feb  6 18:42:40 2000
+++ linux-2.4.20-pre7/include/asm-ia64/vga.h	Thu Sep 12 20:01:49 2002
@@ -1,22 +1,39 @@
+#ifndef _ASM_IA64_VGA_H
+#define _ASM_IA64_VGA_H
+
 /*
  *	Access to VGA videoram
  *
  *	(c) 1998 Martin Mares <mj@ucw.cz>
  *	(c) 1999 Asit Mallick <asit.k.mallick@intel.com>
  *	(c) 1999 Don Dugger <don.dugger@intel.com>
+ *	Copyright (C) 2002 Hewlett-Packard Co
  */
-
-#ifndef __ASM_IA64_VGA_H_
-#define __ASM_IA64_VGA_H_
-
 /*
- * On the PC, we can just recalculate addresses and then access the
- * videoram directly without any black magic.
+ * 2002/07/19	davidm@hpl.hp.com	Access frame-buffer memory via readX/writeX.
  */
 
+#include <asm/io.h>
+
+#define VT_BUF_HAVE_RW
+
 #define VGA_MAP_MEM(x)	((unsigned long) ioremap((x), 0))
 
-#define vga_readb(x)	(*(x))
-#define vga_writeb(x,y)	(*(y) = (x))
+#define vga_readb	__raw_readb
+#define vga_writeb	__raw_writeb
+
+extern inline void
+scr_writew (u16 val, volatile u16 *addr)
+{
+	/* Note: ADDR may point to normal memory.  That's OK on ia64.  */
+	__raw_writew(val, (unsigned long) addr);
+}
+
+extern inline u16
+scr_readw (volatile const u16 *addr)
+{
+	/* Note: ADDR may point to normal memory.  That's OK on ia64.  */
+	return __raw_readw((unsigned long) addr);
+}
 
-#endif /* __ASM_IA64_VGA_H_ */
+#endif /* _ASM_IA64_VGA_H */
diff -urN linux-2.4.20-pre6/include/asm-m68k/unistd.h linux-2.4.20-pre7/include/asm-m68k/unistd.h
--- linux-2.4.20-pre6/include/asm-m68k/unistd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-m68k/unistd.h	Thu Sep 12 20:01:49 2002
@@ -225,6 +225,18 @@
 #define __NR_getdents64		220
 #define __NR_gettid		221
 #define __NR_tkill		222
+#define __NR_setxattr		223
+#define __NR_lsetxattr		224
+#define __NR_fsetxattr		225
+#define __NR_getxattr		226
+#define __NR_lgetxattr		227
+#define __NR_fgetxattr		228
+#define __NR_listxattr		229
+#define __NR_llistxattr		230
+#define __NR_flistxattr		231
+#define __NR_removexattr	232
+#define __NR_lremovexattr	233
+#define __NR_fremovexattr	234
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
diff -urN linux-2.4.20-pre6/include/asm-mips/addrspace.h linux-2.4.20-pre7/include/asm-mips/addrspace.h
--- linux-2.4.20-pre6/include/asm-mips/addrspace.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/addrspace.h	Thu Sep 12 20:01:49 2002
@@ -92,7 +92,7 @@
 #define K_CALG_NOTUSED		6
 #define K_CALG_UNCACHED_ACCEL	7
 
-#define TO_PHYS_MASK		0xfffffffff			/* 36 bit */
+#define TO_PHYS_MASK			0xfffffffffULL		/* 36 bit */
 
 /*
  * 64-bit address conversions
diff -urN linux-2.4.20-pre6/include/asm-mips/asm.h linux-2.4.20-pre7/include/asm-mips/asm.h
--- linux-2.4.20-pre6/include/asm-mips/asm.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/asm.h	Thu Sep 12 20:01:49 2002
@@ -96,7 +96,7 @@
 #define	PANIC(msg)                                      \
 		.set	push;				\
 		.set	reorder;                        \
-		la	a0,8f;                          \
+		PTR_LA	a0,8f;                          \
 		jal	panic;                          \
 9:		b	9b;                             \
 		.set	pop;				\
@@ -108,7 +108,7 @@
 #define PRINT(string)                                   \
 		.set	push;				\
 		.set	reorder;                        \
-		la	a0,8f;                          \
+		PTR_LA	a0,8f;                          \
 		jal	printk;                         \
 		.set	pop;				\
 		TEXT(string)
@@ -172,7 +172,7 @@
 		.set	push;				\
 		.set	reorder;			\
 		bnez	rt,9f;                          \
-		move	rd,rt;                          \
+		move	rd,rs;                          \
 		.set	pop;				\
 9:
 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
diff -urN linux-2.4.20-pre6/include/asm-mips/asmmacro.h linux-2.4.20-pre7/include/asm-mips/asmmacro.h
--- linux-2.4.20-pre6/include/asm-mips/asmmacro.h	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/include/asm-mips/asmmacro.h	Thu Sep 12 20:01:49 2002
@@ -7,8 +7,22 @@
 #ifndef _ASM_ASMMACRO_H
 #define _ASM_ASMMACRO_H
 
+#include <linux/config.h>
 #include <asm/offset.h>
 
+#ifdef CONFIG_CPU_SB1
+#define FPU_ENABLE_HAZARD		\
+	.set	push;			\
+	.set	noreorder;		\
+	.set	mips2;			\
+	SSNOP;				\
+	bnezl	$0, .+4;		\
+	 SSNOP;				\
+	.set	pop
+#else
+#define FPU_ENABLE_HAZARD
+#endif
+
 #define FPU_SAVE_DOUBLE(thread, tmp) \
 	cfc1	tmp,  fcr31;                    \
 	sdc1	$f0,  (THREAD_FPU + 0x000)(thread); \
@@ -29,41 +43,79 @@
 	sdc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
 	sw	tmp,  (THREAD_FPU + 0x100)(thread)
 
+#ifdef __LITTLE_ENDIAN
 #define FPU_SAVE_SINGLE(thread,tmp)                 \
 	cfc1	tmp,  fcr31;                        \
 	swc1	$f0,  (THREAD_FPU + 0x000)(thread); \
-	swc1	$f1,  (THREAD_FPU + 0x008)(thread); \
+	swc1	$f1,  (THREAD_FPU + 0x004)(thread); \
 	swc1	$f2,  (THREAD_FPU + 0x010)(thread); \
-	swc1	$f3,  (THREAD_FPU + 0x018)(thread); \
+	swc1	$f3,  (THREAD_FPU + 0x014)(thread); \
 	swc1	$f4,  (THREAD_FPU + 0x020)(thread); \
-	swc1	$f5,  (THREAD_FPU + 0x028)(thread); \
+	swc1	$f5,  (THREAD_FPU + 0x024)(thread); \
 	swc1	$f6,  (THREAD_FPU + 0x030)(thread); \
-	swc1	$f7,  (THREAD_FPU + 0x038)(thread); \
+	swc1	$f7,  (THREAD_FPU + 0x034)(thread); \
 	swc1	$f8,  (THREAD_FPU + 0x040)(thread); \
-	swc1	$f9,  (THREAD_FPU + 0x048)(thread); \
+	swc1	$f9,  (THREAD_FPU + 0x044)(thread); \
 	swc1	$f10, (THREAD_FPU + 0x050)(thread); \
-	swc1	$f11, (THREAD_FPU + 0x058)(thread); \
+	swc1	$f11, (THREAD_FPU + 0x054)(thread); \
 	swc1	$f12, (THREAD_FPU + 0x060)(thread); \
-	swc1	$f13, (THREAD_FPU + 0x068)(thread); \
+	swc1	$f13, (THREAD_FPU + 0x064)(thread); \
 	swc1	$f14, (THREAD_FPU + 0x070)(thread); \
-	swc1	$f15, (THREAD_FPU + 0x078)(thread); \
+	swc1	$f15, (THREAD_FPU + 0x074)(thread); \
 	swc1	$f16, (THREAD_FPU + 0x080)(thread); \
-	swc1	$f17, (THREAD_FPU + 0x088)(thread); \
+	swc1	$f17, (THREAD_FPU + 0x084)(thread); \
 	swc1	$f18, (THREAD_FPU + 0x090)(thread); \
-	swc1	$f19, (THREAD_FPU + 0x098)(thread); \
+	swc1	$f19, (THREAD_FPU + 0x094)(thread); \
 	swc1	$f20, (THREAD_FPU + 0x0a0)(thread); \
-	swc1	$f21, (THREAD_FPU + 0x0a8)(thread); \
+	swc1	$f21, (THREAD_FPU + 0x0a4)(thread); \
 	swc1	$f22, (THREAD_FPU + 0x0b0)(thread); \
-	swc1	$f23, (THREAD_FPU + 0x0b8)(thread); \
+	swc1	$f23, (THREAD_FPU + 0x0b4)(thread); \
 	swc1	$f24, (THREAD_FPU + 0x0c0)(thread); \
-	swc1	$f25, (THREAD_FPU + 0x0c8)(thread); \
+	swc1	$f25, (THREAD_FPU + 0x0c4)(thread); \
 	swc1	$f26, (THREAD_FPU + 0x0d0)(thread); \
-	swc1	$f27, (THREAD_FPU + 0x0d8)(thread); \
+	swc1	$f27, (THREAD_FPU + 0x0d4)(thread); \
 	swc1	$f28, (THREAD_FPU + 0x0e0)(thread); \
-	swc1	$f29, (THREAD_FPU + 0x0e8)(thread); \
+	swc1	$f29, (THREAD_FPU + 0x0e4)(thread); \
 	swc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
-	swc1	$f31, (THREAD_FPU + 0x0f8)(thread); \
+	swc1	$f31, (THREAD_FPU + 0x0f4)(thread); \
+	sw	tmp,  (THREAD_FPU + 0x100)(thread)
+#else
+#define FPU_SAVE_SINGLE(thread,tmp)                 \
+	cfc1	tmp,  fcr31;                        \
+	swc1	$f0,  (THREAD_FPU + 0x004)(thread); \
+	swc1	$f1,  (THREAD_FPU + 0x000)(thread); \
+	swc1	$f2,  (THREAD_FPU + 0x014)(thread); \
+	swc1	$f3,  (THREAD_FPU + 0x010)(thread); \
+	swc1	$f4,  (THREAD_FPU + 0x024)(thread); \
+	swc1	$f5,  (THREAD_FPU + 0x020)(thread); \
+	swc1	$f6,  (THREAD_FPU + 0x034)(thread); \
+	swc1	$f7,  (THREAD_FPU + 0x030)(thread); \
+	swc1	$f8,  (THREAD_FPU + 0x044)(thread); \
+	swc1	$f9,  (THREAD_FPU + 0x040)(thread); \
+	swc1	$f10, (THREAD_FPU + 0x054)(thread); \
+	swc1	$f11, (THREAD_FPU + 0x050)(thread); \
+	swc1	$f12, (THREAD_FPU + 0x064)(thread); \
+	swc1	$f13, (THREAD_FPU + 0x060)(thread); \
+	swc1	$f14, (THREAD_FPU + 0x074)(thread); \
+	swc1	$f15, (THREAD_FPU + 0x070)(thread); \
+	swc1	$f16, (THREAD_FPU + 0x084)(thread); \
+	swc1	$f17, (THREAD_FPU + 0x080)(thread); \
+	swc1	$f18, (THREAD_FPU + 0x094)(thread); \
+	swc1	$f19, (THREAD_FPU + 0x090)(thread); \
+	swc1	$f20, (THREAD_FPU + 0x0a4)(thread); \
+	swc1	$f21, (THREAD_FPU + 0x0a0)(thread); \
+	swc1	$f22, (THREAD_FPU + 0x0b4)(thread); \
+	swc1	$f23, (THREAD_FPU + 0x0b0)(thread); \
+	swc1	$f24, (THREAD_FPU + 0x0c4)(thread); \
+	swc1	$f25, (THREAD_FPU + 0x0c0)(thread); \
+	swc1	$f26, (THREAD_FPU + 0x0d4)(thread); \
+	swc1	$f27, (THREAD_FPU + 0x0d0)(thread); \
+	swc1	$f28, (THREAD_FPU + 0x0e4)(thread); \
+	swc1	$f29, (THREAD_FPU + 0x0e0)(thread); \
+	swc1	$f30, (THREAD_FPU + 0x0f4)(thread); \
+	swc1	$f31, (THREAD_FPU + 0x0f0)(thread); \
 	sw	tmp,  (THREAD_FPU + 0x100)(thread)
+#endif
 
 #define FPU_RESTORE_DOUBLE(thread, tmp) \
 	lw	tmp,  (THREAD_FPU + 0x100)(thread); \
@@ -85,41 +137,79 @@
 	ldc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
 	ctc1	tmp,  fcr31
 
+#ifdef __LITTLE_ENDIAN
 #define FPU_RESTORE_SINGLE(thread,tmp)              \
 	lw	tmp,  (THREAD_FPU + 0x100)(thread); \
 	lwc1	$f0,  (THREAD_FPU + 0x000)(thread); \
-	lwc1	$f1,  (THREAD_FPU + 0x008)(thread); \
+	lwc1	$f1,  (THREAD_FPU + 0x004)(thread); \
 	lwc1	$f2,  (THREAD_FPU + 0x010)(thread); \
-	lwc1	$f3,  (THREAD_FPU + 0x018)(thread); \
+	lwc1	$f3,  (THREAD_FPU + 0x014)(thread); \
 	lwc1	$f4,  (THREAD_FPU + 0x020)(thread); \
-	lwc1	$f5,  (THREAD_FPU + 0x028)(thread); \
+	lwc1	$f5,  (THREAD_FPU + 0x024)(thread); \
 	lwc1	$f6,  (THREAD_FPU + 0x030)(thread); \
-	lwc1	$f7,  (THREAD_FPU + 0x038)(thread); \
+	lwc1	$f7,  (THREAD_FPU + 0x034)(thread); \
 	lwc1	$f8,  (THREAD_FPU + 0x040)(thread); \
-	lwc1	$f9,  (THREAD_FPU + 0x048)(thread); \
+	lwc1	$f9,  (THREAD_FPU + 0x044)(thread); \
 	lwc1	$f10, (THREAD_FPU + 0x050)(thread); \
-	lwc1	$f11, (THREAD_FPU + 0x058)(thread); \
+	lwc1	$f11, (THREAD_FPU + 0x054)(thread); \
 	lwc1	$f12, (THREAD_FPU + 0x060)(thread); \
-	lwc1	$f13, (THREAD_FPU + 0x068)(thread); \
+	lwc1	$f13, (THREAD_FPU + 0x064)(thread); \
 	lwc1	$f14, (THREAD_FPU + 0x070)(thread); \
-	lwc1	$f15, (THREAD_FPU + 0x078)(thread); \
+	lwc1	$f15, (THREAD_FPU + 0x074)(thread); \
 	lwc1	$f16, (THREAD_FPU + 0x080)(thread); \
-	lwc1	$f17, (THREAD_FPU + 0x088)(thread); \
+	lwc1	$f17, (THREAD_FPU + 0x084)(thread); \
 	lwc1	$f18, (THREAD_FPU + 0x090)(thread); \
-	lwc1	$f19, (THREAD_FPU + 0x098)(thread); \
+	lwc1	$f19, (THREAD_FPU + 0x094)(thread); \
 	lwc1	$f20, (THREAD_FPU + 0x0a0)(thread); \
-	lwc1	$f21, (THREAD_FPU + 0x0a8)(thread); \
+	lwc1	$f21, (THREAD_FPU + 0x0a4)(thread); \
 	lwc1	$f22, (THREAD_FPU + 0x0b0)(thread); \
-	lwc1	$f23, (THREAD_FPU + 0x0b8)(thread); \
+	lwc1	$f23, (THREAD_FPU + 0x0b4)(thread); \
 	lwc1	$f24, (THREAD_FPU + 0x0c0)(thread); \
-	lwc1	$f25, (THREAD_FPU + 0x0c8)(thread); \
+	lwc1	$f25, (THREAD_FPU + 0x0c4)(thread); \
 	lwc1	$f26, (THREAD_FPU + 0x0d0)(thread); \
-	lwc1	$f27, (THREAD_FPU + 0x0d8)(thread); \
+	lwc1	$f27, (THREAD_FPU + 0x0d4)(thread); \
 	lwc1	$f28, (THREAD_FPU + 0x0e0)(thread); \
-	lwc1	$f29, (THREAD_FPU + 0x0e8)(thread); \
+	lwc1	$f29, (THREAD_FPU + 0x0e4)(thread); \
 	lwc1	$f30, (THREAD_FPU + 0x0f0)(thread); \
-	lwc1	$f31, (THREAD_FPU + 0x0f8)(thread); \
+	lwc1	$f31, (THREAD_FPU + 0x0f4)(thread); \
+	ctc1	tmp,  fcr31
+#else
+#define FPU_RESTORE_SINGLE(thread,tmp)              \
+	lw	tmp,  (THREAD_FPU + 0x100)(thread); \
+	lwc1	$f0,  (THREAD_FPU + 0x004)(thread); \
+	lwc1	$f1,  (THREAD_FPU + 0x000)(thread); \
+	lwc1	$f2,  (THREAD_FPU + 0x014)(thread); \
+	lwc1	$f3,  (THREAD_FPU + 0x010)(thread); \
+	lwc1	$f4,  (THREAD_FPU + 0x024)(thread); \
+	lwc1	$f5,  (THREAD_FPU + 0x020)(thread); \
+	lwc1	$f6,  (THREAD_FPU + 0x034)(thread); \
+	lwc1	$f7,  (THREAD_FPU + 0x030)(thread); \
+	lwc1	$f8,  (THREAD_FPU + 0x044)(thread); \
+	lwc1	$f9,  (THREAD_FPU + 0x040)(thread); \
+	lwc1	$f10, (THREAD_FPU + 0x054)(thread); \
+	lwc1	$f11, (THREAD_FPU + 0x050)(thread); \
+	lwc1	$f12, (THREAD_FPU + 0x064)(thread); \
+	lwc1	$f13, (THREAD_FPU + 0x060)(thread); \
+	lwc1	$f14, (THREAD_FPU + 0x074)(thread); \
+	lwc1	$f15, (THREAD_FPU + 0x070)(thread); \
+	lwc1	$f16, (THREAD_FPU + 0x084)(thread); \
+	lwc1	$f17, (THREAD_FPU + 0x080)(thread); \
+	lwc1	$f18, (THREAD_FPU + 0x094)(thread); \
+	lwc1	$f19, (THREAD_FPU + 0x090)(thread); \
+	lwc1	$f20, (THREAD_FPU + 0x0a4)(thread); \
+	lwc1	$f21, (THREAD_FPU + 0x0a0)(thread); \
+	lwc1	$f22, (THREAD_FPU + 0x0b4)(thread); \
+	lwc1	$f23, (THREAD_FPU + 0x0b0)(thread); \
+	lwc1	$f24, (THREAD_FPU + 0x0c4)(thread); \
+	lwc1	$f25, (THREAD_FPU + 0x0c0)(thread); \
+	lwc1	$f26, (THREAD_FPU + 0x0d4)(thread); \
+	lwc1	$f27, (THREAD_FPU + 0x0d0)(thread); \
+	lwc1	$f28, (THREAD_FPU + 0x0e4)(thread); \
+	lwc1	$f29, (THREAD_FPU + 0x0e0)(thread); \
+	lwc1	$f30, (THREAD_FPU + 0x0f4)(thread); \
+	lwc1	$f31, (THREAD_FPU + 0x0f0)(thread); \
 	ctc1	tmp,  fcr31
+#endif
 
 #define CPU_SAVE_NONSCRATCH(thread) \
 	sw	s0, THREAD_REG16(thread); \
diff -urN linux-2.4.20-pre6/include/asm-mips/atomic.h linux-2.4.20-pre7/include/asm-mips/atomic.h
--- linux-2.4.20-pre6/include/asm-mips/atomic.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/atomic.h	Thu Sep 12 20:01:49 2002
@@ -57,10 +57,9 @@
  */
 extern __inline__ void atomic_add(int i, atomic_t * v)
 {
-	int	flags;
+	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	save_and_cli(flags);
 	v->counter += i;
 	restore_flags(flags);
 }
@@ -75,20 +74,19 @@
  */
 extern __inline__ void atomic_sub(int i, atomic_t * v)
 {
-	int	flags;
+	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	save_and_cli(flags);
 	v->counter -= i;
 	restore_flags(flags);
 }
 
 extern __inline__ int atomic_add_return(int i, atomic_t * v)
 {
-	int	temp, flags;
+	unsigned long flags;
+	int temp;
 
-	save_flags(flags);
-	cli();
+	save_and_cli(flags);
 	temp = v->counter;
 	temp += i;
 	v->counter = temp;
@@ -99,10 +97,10 @@
 
 extern __inline__ int atomic_sub_return(int i, atomic_t * v)
 {
-	int	temp, flags;
+	unsigned long flags;
+	int temp;
 
-	save_flags(flags);
-	cli();
+	save_and_cli(flags);
 	temp = v->counter;
 	temp -= i;
 	v->counter = temp;
diff -urN linux-2.4.20-pre6/include/asm-mips/au1000.h linux-2.4.20-pre7/include/asm-mips/au1000.h
--- linux-2.4.20-pre6/include/asm-mips/au1000.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/au1000.h	Thu Sep 12 20:01:49 2002
@@ -31,6 +31,7 @@
 #ifndef _AU1000_H_
 #define _AU1000_H_
 
+#include <linux/config.h>
 #include <linux/delay.h>
 #include <asm/io.h>
 
@@ -52,22 +53,34 @@
 	mdelay(ms);
 }
 
-void static inline outb_sync(u8 val, int reg)
+void static inline au_writeb(u8 val, int reg)
 {
-	outb(val, reg);
-	au_sync();
+	*(volatile u8 *)(reg) = val;
 }
 
-void static inline outw_sync(u16 val, int reg)
+void static inline au_writew(u16 val, int reg)
 {
-	outw(val, reg);
-	au_sync();
+	*(volatile u16 *)(reg) = val;
 }
 
-void static inline outl_sync(u32 val, int reg)
+void static inline au_writel(u32 val, int reg)
 {
-	outl(val, reg);
-	au_sync();
+	*(volatile u32 *)(reg) = val;
+}
+
+static inline u8 au_readb(unsigned long port)
+{
+	return (*(volatile u8 *)port);
+}
+
+static inline u16 au_readw(unsigned long port)
+{
+	return (*(volatile u16 *)port);
+}
+
+static inline u32 au_readl(unsigned long port)
+{
+	return (*(volatile u32 *)port);
 }
 
 /* arch/mips/au1000/common/clocks.c */
@@ -300,6 +313,12 @@
 
 #define AU1000_MAX_INTR           63
 
+#define AU1100_SD		2
+#define	AU1100_GPIO_208_215	29
+// REDEFINE SECONDARY GPIO BLOCK INTO IC1 CONTROLLER HERE
+
+
+
 /* Programmable Counters 0 and 1 */
 #define SYS_BASE                   0xB1900000
 #define SYS_COUNTER_CNTRL          (SYS_BASE + 0x14)
@@ -339,11 +358,36 @@
 #define SYS_RTCMATCH2               (SYS_BASE + 0x54)
 #define SYS_RTCREAD                 (SYS_BASE + 0x58)
 
-
 /* I2S Controller */
 #define I2S_DATA                    0xB1000000
-#define I2S_CONFIG                  0xB1000001
-#define I2S_ENABLE                  0xB1000002
+  #define I2S_DATA_MASK        (0xffffff)
+#define I2S_CONFIG                0xB1000004
+  #define I2S_CONFIG_XU        (1<<25)
+  #define I2S_CONFIG_XO        (1<<24)
+  #define I2S_CONFIG_RU        (1<<23)
+  #define I2S_CONFIG_RO        (1<<22)
+  #define I2S_CONFIG_TR        (1<<21)
+  #define I2S_CONFIG_TE        (1<<20)
+  #define I2S_CONFIG_TF        (1<<19)
+  #define I2S_CONFIG_RR        (1<<18)
+  #define I2S_CONFIG_RE        (1<<17)
+  #define I2S_CONFIG_RF        (1<<16)
+  #define I2S_CONFIG_PD        (1<<11)
+  #define I2S_CONFIG_LB        (1<<10)
+  #define I2S_CONFIG_IC        (1<<9)
+  #define I2S_CONFIG_FM_BIT    7
+  #define I2S_CONFIG_FM_MASK     (0x3 << I2S_CONFIG_FM_BIT)
+    #define I2S_CONFIG_FM_I2S    (0x0 << I2S_CONFIG_FM_BIT)
+    #define I2S_CONFIG_FM_LJ     (0x1 << I2S_CONFIG_FM_BIT)
+    #define I2S_CONFIG_FM_RJ     (0x2 << I2S_CONFIG_FM_BIT)
+  #define I2S_CONFIG_TN        (1<<6)
+  #define I2S_CONFIG_RN        (1<<5)
+  #define I2S_CONFIG_SZ_BIT    0
+  #define I2S_CONFIG_SZ_MASK     (0x1F << I2S_CONFIG_SZ_BIT)
+
+#define I2S_CONTROL                0xB1000008
+  #define I2S_CONTROL_D         (1<<1)
+  #define I2S_CONTROL_CE        (1<<0)
 
 /* USB Host Controller */
 // We pass USB_OHCI_BASE to ioremap, so it needs to be a physical address
@@ -398,12 +442,13 @@
 #define AU1000_ETH1_BASE          0xB0510000
 #define AU1500_ETH0_BASE	  0xB1500000
 #define AU1500_ETH1_BASE	  0xB1510000
+#define AU1100_ETH0_BASE	  0xB0500000
 
 /* 4 byte offsets from AU1000_ETH_BASE */
 #define MAC_CONTROL                     0x0
-  #define MAC_RX_ENABLE               (1<<2) 
+  #define MAC_RX_ENABLE               (1<<2)
   #define MAC_TX_ENABLE               (1<<3)
-  #define MAC_DEF_CHECK               (1<<5) 
+  #define MAC_DEF_CHECK               (1<<5)
   #define MAC_SET_BL(X)       (((X)&0x3)<<6)
   #define MAC_AUTO_PAD                (1<<8)
   #define MAC_DISABLE_RETRY          (1<<10)
@@ -428,7 +473,7 @@
 #define MAC_MCAST_LOW                  0x10
 #define MAC_MII_CNTRL                  0x14
   #define MAC_MII_BUSY                (1<<0)
-  #define MAC_MII_READ                     0 
+  #define MAC_MII_READ                     0
   #define MAC_MII_WRITE               (1<<1)
   #define MAC_SET_MII_SELECT_REG(X)   (((X)&0x1f)<<6)
   #define MAC_SET_MII_SELECT_PHY(X)   (((X)&0x1f)<<11)
@@ -446,6 +491,8 @@
 #define AU1000_MAC1_ENABLE       0xB0520004
 #define AU1500_MAC0_ENABLE       0xB1520000
 #define AU1500_MAC1_ENABLE       0xB1520004
+#define AU1100_MAC0_ENABLE       0xB0520000
+
   #define MAC_EN_CLOCK_ENABLE         (1<<0)
   #define MAC_EN_RESET0               (1<<1)
   #define MAC_EN_TOSS                 (0<<2)
@@ -510,7 +557,7 @@
   #define RX_FILTER_FAIL             (1<<29)
   #define RX_PACKET_FILTER           (1<<30)
   #define RX_MISSED_FRAME            (1<<31)
-  
+
   #define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN |  \
                     RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
                     RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
@@ -628,12 +675,44 @@
 
 /* SSIO */
 #define SSI0_STATUS                0xB1600000
+  #define SSI_STATUS_BF              (1<<4)
+  #define SSI_STATUS_OF              (1<<3)
+  #define SSI_STATUS_UF              (1<<2)
+  #define SSI_STATUS_D               (1<<1)
+  #define SSI_STATUS_B               (1<<0)
 #define SSI0_INT                   0xB1600004
+  #define SSI_INT_OI                 (1<<3)
+  #define SSI_INT_UI                 (1<<2)
+  #define SSI_INT_DI                 (1<<1)
 #define SSI0_INT_ENABLE            0xB1600008
+  #define SSI_INTE_OIE               (1<<3)
+  #define SSI_INTE_UIE               (1<<2)
+  #define SSI_INTE_DIE               (1<<1)
 #define SSI0_CONFIG                0xB1600020
+  #define SSI_CONFIG_AO              (1<<24)
+  #define SSI_CONFIG_DO              (1<<23)
+  #define SSI_CONFIG_ALEN_BIT        20
+    #define SSI_CONFIG_ALEN_MASK       (0x7<<20)
+  #define SSI_CONFIG_DLEN_BIT        16
+    #define SSI_CONFIG_DLEN_MASK       (0x7<<16)
+  #define SSI_CONFIG_DD              (1<<11)
+  #define SSI_CONFIG_AD              (1<<10)
+  #define SSI_CONFIG_BM_BIT          8
+    #define SSI_CONFIG_BM_MASK         (0x3<<8)
+  #define SSI_CONFIG_CE              (1<<7)
+  #define SSI_CONFIG_DP              (1<<6)
+  #define SSI_CONFIG_DL              (1<<5)
+  #define SSI_CONFIG_EP              (1<<4)
 #define SSI0_ADATA                 0xB1600024
+  #define SSI_AD_D                   (1<<24)
+  #define SSI_AD_ADDR_BIT            16
+    #define SSI_AD_ADDR_MASK           (0xff<<16)
+  #define SSI_AD_DATA_BIT            0
+    #define SSI_AD_DATA_MASK           (0xfff<<0)
 #define SSI0_CLKDIV                0xB1600028
 #define SSI0_CONTROL               0xB1600100
+  #define SSI_CONTROL_CD             (1<<1)
+  #define SSI_CONTROL_E              (1<<0)
 
 /* SSI1 */
 #define SSI1_STATUS                0xB1680000
@@ -685,12 +764,29 @@
 
 /* GPIO */
 #define SYS_PINFUNC               0xB190002C
+  #define SYS_PF_USB			(1<<15)	/* 2nd USB device/host */
+  #define SYS_PF_U3			(1<<14)	/* GPIO23/U3TXD */
+  #define SYS_PF_U2			(1<<13) /* GPIO22/U2TXD */
+  #define SYS_PF_U1			(1<<12) /* GPIO21/U1TXD */
+  #define SYS_PF_SRC			(1<<11)	/* GPIO6/SROMCKE */
+  #define SYS_PF_CK5			(1<<10)	/* GPIO3/CLK5 */
+  #define SYS_PF_CK4			(1<<9)	/* GPIO2/CLK4 */
+  #define SYS_PF_IRF			(1<<8)	/* GPIO15/IRFIRSEL */
+  #define SYS_PF_UR3			(1<<7)	/* GPIO[14:9]/UART3 */
+  #define SYS_PF_I2D			(1<<6)	/* GPIO8/I2SDI */
+  #define SYS_PF_I2S			(1<<5)	/* I2S/GPIO[29:31] */
+  #define SYS_PF_NI2			(1<<4)	/* NI2/GPIO[24:28] */
+  #define SYS_PF_U0			(1<<3)	/* U0TXD/GPIO20 */
+  #define SYS_PF_RD			(1<<2)	/* IRTXD/GPIO19 */
+  #define SYS_PF_A97			(1<<1)	/* AC97/SSL1 */
+  #define SYS_PF_S0			(1<<0)	/* SSI_0/GPIO[16:18] */
 #define SYS_TRIOUTRD              0xB1900100
 #define SYS_TRIOUTCLR             0xB1900100
 #define SYS_OUTPUTRD              0xB1900108
 #define SYS_OUTPUTSET             0xB1900108
 #define SYS_OUTPUTCLR             0xB190010C
 #define SYS_PINSTATERD            0xB1900110
+#define SYS_PININPUTEN            0xB1900110
 
 /* GPIO2, Au1500 only */
 #define GPIO2_BASE                0xB1700000
@@ -712,8 +808,64 @@
 
 /* Clock Controller */
 #define SYS_FREQCTRL0             0xB1900020
+  #define SYS_FC_FRDIV2_BIT         22
+  #define SYS_FC_FRDIV2_MASK        (0xff << FQC2_FRDIV2_BIT)
+  #define SYS_FC_FE2                (1<<21)
+  #define SYS_FC_FS2                (1<<20)
+  #define SYS_FC_FRDIV1_BIT         12
+  #define SYS_FC_FRDIV1_MASK        (0xff << FQC2_FRDIV1_BIT)
+  #define SYS_FC_FE1                (1<<11)
+  #define SYS_FC_FS1                (1<<10)
+  #define SYS_FC_FRDIV0_BIT         2
+  #define SYS_FC_FRDIV0_MASK        (0xff << FQC2_FRDIV0_BIT)
+  #define SYS_FC_FE0                (1<<1)
+  #define SYS_FC_FS0                (1<<0)
 #define SYS_FREQCTRL1             0xB1900024
+  #define SYS_FC_FRDIV5_BIT         22
+  #define SYS_FC_FRDIV5_MASK        (0xff << FQC2_FRDIV5_BIT)
+  #define SYS_FC_FE5                (1<<21)
+  #define SYS_FC_FS5                (1<<20)
+  #define SYS_FC_FRDIV4_BIT         12
+  #define SYS_FC_FRDIV4_MASK        (0xff << FQC2_FRDIV4_BIT)
+  #define SYS_FC_FE4                (1<<11)
+  #define SYS_FC_FS4                (1<<10)
+  #define SYS_FC_FRDIV3_BIT         2
+  #define SYS_FC_FRDIV3_MASK        (0xff << FQC2_FRDIV3_BIT)
+  #define SYS_FC_FE3                (1<<1)
+  #define SYS_FC_FS3                (1<<0)
 #define SYS_CLKSRC                0xB1900028
+  #define SYS_CS_ME1_BIT            27
+  #define SYS_CS_ME1_MASK           (0x7<<CSC_ME1_BIT)
+  #define SYS_CS_DE1                (1<<26)
+  #define SYS_CS_CE1                (1<<25)
+  #define SYS_CS_ME0_BIT            22
+  #define SYS_CS_ME0_MASK           (0x7<<CSC_ME0_BIT)
+  #define SYS_CS_DE0                (1<<21)
+  #define SYS_CS_CE0                (1<<20)
+  #define SYS_CS_MI2_BIT            17
+  #define SYS_CS_MI2_MASK           (0x7<<CSC_MI2_BIT)
+  #define SYS_CS_DI2                (1<<16)
+  #define SYS_CS_CI2                (1<<15)
+  #define SYS_CS_MUH_BIT            12
+  #define SYS_CS_MUH_MASK           (0x7<<CSC_MUH_BIT)
+  #define SYS_CS_DUH                (1<<11)
+  #define SYS_CS_CUH                (1<<10)
+  #define SYS_CS_MUD_BIT            7
+  #define SYS_CS_MUD_MASK           (0x7<<CSC_MUD_BIT)
+  #define SYS_CS_DUD                (1<<6)
+  #define SYS_CS_CUD                (1<<5)
+  #define SYS_CS_MIR_BIT            2
+  #define SYS_CS_MIR_MASK           (0x7<<CSC_MIR_BIT)
+  #define SYS_CS_DIR                (1<<1)
+  #define SYS_CS_CIR                (1<<0)
+
+  #define SYS_CS_MUX_AUX            0x1
+  #define SYS_CS_MUX_FQ0            0x2
+  #define SYS_CS_MUX_FQ1            0x3
+  #define SYS_CS_MUX_FQ2            0x4
+  #define SYS_CS_MUX_FQ3            0x5
+  #define SYS_CS_MUX_FQ4            0x6
+  #define SYS_CS_MUX_FQ5            0x7
 #define SYS_CPUPLL                0xB1900060
 #define SYS_AUXPLL                0xB1900064
 
@@ -768,11 +920,19 @@
 
 #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
+/* All of our structures, like pci resource, have 32 bit members.
+ * Drivers are expected to do an ioremap on the PCI MEM resource, but it's
+ * hard to store 0x4 0000 0000 in a 32 bit type.  We require a small patch
+ * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and
+ * (u32)Au1500_PCI_MEM_END and change those to the full 36 bit PCI MEM
+ * addresses.  For PCI IO, it's simpler because we get to do the ioremap
+ * ourselves and then adjust the device's resources.
+ */
+#define Au1500_EXT_CFG            0x600000000
+#define Au1500_EXT_CFG_TYPE1      0x680000000
+#define Au1500_PCI_IO_START       0x500000000
+#define Au1500_PCI_IO_END         0x5000FFFFF
+#define Au1500_PCI_MEM_START      0x440000000
+#define Au1500_PCI_MEM_END        0x443FFFFFF
 
 #endif
diff -urN linux-2.4.20-pre6/include/asm-mips/au1000_dma.h linux-2.4.20-pre7/include/asm-mips/au1000_dma.h
--- linux-2.4.20-pre6/include/asm-mips/au1000_dma.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/au1000_dma.h	Thu Sep 12 20:01:49 2002
@@ -44,6 +44,7 @@
 
 /* DMA Channel Register Offsets */
 #define DMA_MODE_SET		0x00000000
+#define DMA_MODE_READ		DMA_MODE_SET
 #define DMA_MODE_CLEAR		0x00000004
 /* DMA Mode register bits follow */
 #define DMA_DAH_MASK		(0x0f << 20)
@@ -101,15 +102,21 @@
 struct dma_chan {
 	int dev_id;		// this channel is allocated if >=0, free otherwise
 	unsigned int io;
-	int irq;
 	const char *dev_str;
+	int irq;
+	void *irq_dev;
 	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 int request_au1000_dma(int dev_id,
+			      const char *dev_str,
+			      void (*irqhandler)(int, void *,
+						 struct pt_regs *),
+			      unsigned long irqflags,
+			      void *irq_dev_id);
 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);
@@ -162,45 +169,75 @@
 	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)
+static __inline__ void start_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);
+	au_writel(DMA_GO, chan->io + DMA_MODE_SET);
 }
 
 #define DMA_HALT_POLL 0x5000
 
-static __inline__ void disable_dma(unsigned int dmanr)
+static __inline__ void halt_dma(unsigned int dmanr)
 {
-	int i;
 	struct dma_chan *chan = get_dma_chan(dmanr);
+	int i;
 	if (!chan)
 		return;
 
-	au_writel(DMA_D1 | DMA_D0 | DMA_GO, chan->io + DMA_MODE_CLEAR);
-
+	au_writel(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)
+		if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
 			break;
-	if (i == DMA_HALT_POLL) {
-		printk(KERN_INFO "disable_dma: HALT poll expired!\n");
-	} else {
+	if (i == DMA_HALT_POLL)
+		printk(KERN_INFO "halt_dma: HALT poll expired!\n");
+}
+
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return;
+
+	halt_dma(dmanr);
+
 		// now we can disable the buffers
 		au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
-	}
 }
 
+static __inline__ int dma_halted(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return 1;
+	return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
+}
+
+/* initialize a DMA channel */
+static __inline__ void init_dma(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	u32 mode;
+	if (!chan)
+		return;
+
+	disable_dma(dmanr);
+
+	// set device FIFO address
+	au_writel(virt_to_phys((void *) chan->fifo_addr),
+		  chan->io + DMA_PERIPHERAL_ADDR);
+
+	mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
+	if (chan->irq)
+		mode |= DMA_IE;
+
+	au_writel(~mode, chan->io + DMA_MODE_CLEAR);
+	au_writel(mode, chan->io + DMA_MODE_SET);
+}
 
 /*
  * set mode for a specific DMA channel
@@ -211,12 +248,21 @@
 	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.
+	 * set_dma_mode is only allowed to change endianess, direction,
+	 * transfer size, device FIFO width, and coherency settings.
+	 * Make sure anything else is masked off.
 	 */
 	mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
-	chan->mode = mode;
+	chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
+	chan->mode |= mode;
+}
+
+static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
+{
+	struct dma_chan *chan = get_dma_chan(dmanr);
+	if (!chan)
+		return 0;
+	return chan->mode;
 }
 
 static __inline__ int get_dma_active_buffer(unsigned int dmanr)
@@ -224,7 +270,7 @@
 	struct dma_chan *chan = get_dma_chan(dmanr);
 	if (!chan)
 		return -1;
-	return (au_readl(chan->io + DMA_MODE_SET) & DMA_AB) ? 1 : 0;
+	return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
 }
 
 
@@ -345,7 +391,7 @@
 	if (!chan)
 		return 0;
 
-    return au_readl(chan->io + DMA_MODE_SET) & (DMA_D0 | DMA_D1);
+    return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
 }
 
 
@@ -371,7 +417,7 @@
 	if (!chan)
 		return 0;
 
-	curBufCntReg = (au_readl(chan->io + DMA_MODE_SET) & DMA_AB) ?
+	curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
 	    DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;
 
 	count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
diff -urN linux-2.4.20-pre6/include/asm-mips/au1000_gpio.h linux-2.4.20-pre7/include/asm-mips/au1000_gpio.h
--- linux-2.4.20-pre6/include/asm-mips/au1000_gpio.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/au1000_gpio.h	Thu Sep 12 20:01:49 2002
@@ -44,7 +44,7 @@
 #define AU1000GPIO_TRISTATE	_IOW (AU1000GPIO_IOC_MAGIC, 4, int)
 #define AU1000GPIO_AVAIL_MASK	_IOR (AU1000GPIO_IOC_MAGIC, 5, int)
 
-#ifdef __KERNEL__ 
+#ifdef __KERNEL__
 extern u32 get_au1000_avail_gpio_mask(void);
 extern int au1000gpio_tristate(u32 data);
 extern int au1000gpio_in(u32 *data);
diff -urN linux-2.4.20-pre6/include/asm-mips/au1000_pcmcia.h linux-2.4.20-pre7/include/asm-mips/au1000_pcmcia.h
--- linux-2.4.20-pre6/include/asm-mips/au1000_pcmcia.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/au1000_pcmcia.h	Thu Sep 12 20:01:49 2002
@@ -23,12 +23,11 @@
  *
  * ########################################################################
  *
- * 
+ *
  */
 #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)
@@ -60,6 +59,8 @@
 	unsigned int irq;
 };
 
+typedef u_int memaddr_t;	/* fix me */
+
 struct au1000_pcmcia_socket {
 	socket_state_t        cs_state;
 	struct pcmcia_state   k_state;
@@ -68,7 +69,8 @@
 	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;
+	u32                   virt_io;
+	memaddr_t             phys_attr, phys_mem;	/*FIX ME*/
 	unsigned short        speed_io, speed_attr, speed_mem;
 };
 
@@ -84,10 +86,10 @@
 	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;
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
+extern struct pcmcia_low_level pb1x00_pcmcia_ops;
+#else
+error unknown Au1000 board
 #endif
 
 #endif /* __ASM_AU1000_PCMCIA_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/au1000_usbdev.h linux-2.4.20-pre7/include/asm-mips/au1000_usbdev.h
--- linux-2.4.20-pre6/include/asm-mips/au1000_usbdev.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/au1000_usbdev.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,73 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1000 USB Device-Side 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.
+ */
+
+#define USBDEV_REV 0x0110 // BCD
+#define USBDEV_EP0_MAX_PACKET_SIZE 64
+
+typedef enum {
+	ATTACHED = 0,
+	POWERED,
+	DEFAULT,
+	ADDRESS,
+	CONFIGURED
+} usbdev_state_t;
+
+typedef enum {
+	CB_NEW_STATE = 0,
+	CB_PKT_COMPLETE
+} usbdev_cb_type_t;
+
+
+typedef struct usbdev_pkt {
+	int                ep_addr;    // ep addr this packet routed to
+	int                size;       // size of payload in bytes
+	unsigned           status;     // packet status
+	struct usbdev_pkt* next;       // function layer can't touch this
+	u8                 payload[0]; // the payload
+} usbdev_pkt_t;
+
+#define PKT_STATUS_ACK  (1<<0)
+#define PKT_STATUS_NAK  (1<<1)
+#define PKT_STATUS_SU   (1<<2)
+
+extern int usbdev_init(struct usb_device_descriptor* dev_desc,
+		       struct usb_config_descriptor* config_desc,
+		       struct usb_interface_descriptor* if_desc,
+		       struct usb_endpoint_descriptor* ep_desc,
+		       struct usb_string_descriptor* str_desc[],
+		       void (*cb)(usbdev_cb_type_t, unsigned long, void *),
+		       void* cb_data);
+
+extern void usbdev_exit(void);
+
+extern int usbdev_alloc_packet  (int ep_addr, int data_size,
+				 usbdev_pkt_t** pkt);
+extern int usbdev_send_packet   (int ep_addr, usbdev_pkt_t* pkt);
+extern int usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt);
+extern int usbdev_get_byte_count(int ep_addr);
diff -urN linux-2.4.20-pre6/include/asm-mips/bcache.h linux-2.4.20-pre7/include/asm-mips/bcache.h
--- linux-2.4.20-pre6/include/asm-mips/bcache.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/bcache.h	Thu Sep 12 20:01:49 2002
@@ -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);
diff -urN linux-2.4.20-pre6/include/asm-mips/bitops.h linux-2.4.20-pre7/include/asm-mips/bitops.h
--- linux-2.4.20-pre6/include/asm-mips/bitops.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/bitops.h	Thu Sep 12 20:01:49 2002
@@ -159,7 +159,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 extern __inline__ int
@@ -191,7 +191,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -213,7 +213,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 extern __inline__ int
@@ -246,7 +246,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -268,7 +268,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 extern __inline__ int
@@ -300,7 +300,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -427,7 +427,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
@@ -451,7 +451,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -473,7 +473,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
@@ -497,7 +497,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -519,7 +519,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
@@ -543,7 +543,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -644,7 +644,7 @@
 	unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
 	int set = 0, bit = offset & 31, res;
 	unsigned long dummy;
-	
+
 	if (bit) {
 		/*
 		 * Look for zero in first byte
@@ -891,7 +891,7 @@
 #define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
 #define ext2_find_next_zero_bit(addr, size, offset) \
                 find_next_zero_bit((addr), (size), (offset))
- 
+
 #endif /* !(__MIPSEB__) */
 
 /*
diff -urN linux-2.4.20-pre6/include/asm-mips/bootinfo.h linux-2.4.20-pre7/include/asm-mips/bootinfo.h
--- linux-2.4.20-pre6/include/asm-mips/bootinfo.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/bootinfo.h	Thu Sep 12 20:01:49 2002
@@ -49,7 +49,7 @@
 #define MACH_OLIVETTI_M700      2	/* Olivetti M700-10 (-15 ??)    */
 
 /*
- * Valid machtype for group DEC 
+ * Valid machtype for group DEC
  */
 #define MACH_DSUNKNOWN		0
 #define MACH_DS23100		1	/* DECstation 2100 or 3100	*/
@@ -96,10 +96,11 @@
 /*
  * 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 */
+#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 */
+#define MACH_NEC_ROCKHOPPERII	4	/* Rockhopper II base board */
 
 /*
  * Valid machtype for group BAGET
@@ -121,17 +122,18 @@
 /*
  * Valid machtype for group MOMENCO
  */
-#define MACH_MOMENCO_OCELOT	0
- 
+#define MACH_MOMENCO_OCELOT		0
+#define MACH_MOMENCO_OCELOT_G		1
+
 /*
  * 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 */
+#define MACH_IVR		0	/* IVR eval board */
 
 /*
  * Valid machtype for group PHILIPS
@@ -150,18 +152,21 @@
 #define MACH_PALLAS		0
 #define MACH_TOPAS		1
 #define MACH_JMR		2
-#define MACH_TOSHIBA_JMR3927    3      /* JMR-TX3927 CPU/IO board */
+#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 MACH_PB1000		0	/* Au1000-based eval board */
+#define MACH_PB1100		1	/* Au1100-based eval board */
+#define MACH_PB1500		2	/* Au1500-based eval board */
+
 /*
  * Valid machtype for group NEC_VR41XX
  */
-#define MACH_NEC_OSPREY                0       /* Osprey eval board */
+#define MACH_NEC_OSPREY		0	/* Osprey eval board */
+#define MACH_NEC_EAGLE		1	/* NEC Eagle/Hawk board */
+#define MACH_ZAO_CAPCELLA	2	/* ZAO Networks Capcella */
 
 #define CL_SIZE			(256)
 
diff -urN linux-2.4.20-pre6/include/asm-mips/cacheops.h linux-2.4.20-pre7/include/asm-mips/cacheops.h
--- linux-2.4.20-pre6/include/asm-mips/cacheops.h	Thu Jun 26 12:33:39 1997
+++ linux-2.4.20-pre7/include/asm-mips/cacheops.h	Thu Sep 12 20:01:49 2002
@@ -35,6 +35,7 @@
 #define Hit_Writeback_Inv_D	0x15
 					/* 0x16 is unused */
 #define Hit_Writeback_Inv_SD	0x17
+#define R5K_Page_Invalidate_S	0x17
 #define Hit_Writeback_I		0x18
 #define Hit_Writeback_D		0x19
 					/* 0x1a is unused */
diff -urN linux-2.4.20-pre6/include/asm-mips/checksum.h linux-2.4.20-pre7/include/asm-mips/checksum.h
--- linux-2.4.20-pre6/include/asm-mips/checksum.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/checksum.h	Thu Sep 12 20:01:49 2002
@@ -84,7 +84,7 @@
 
 	return sum;
 }
- 
+
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
  *	which always checksum on 4 octet boundaries.
@@ -200,7 +200,7 @@
 						     struct in6_addr *daddr,
 						     __u32 len,
 						     unsigned short proto,
-						     unsigned int sum) 
+						     unsigned int sum)
 {
 	__asm__(
 	".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t"
diff -urN linux-2.4.20-pre6/include/asm-mips/cobalt/cobalt.h linux-2.4.20-pre7/include/asm-mips/cobalt/cobalt.h
--- linux-2.4.20-pre6/include/asm-mips/cobalt/cobalt.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/cobalt/cobalt.h	Thu Sep 12 20:01:49 2002
@@ -10,8 +10,8 @@
  * Copyright (C) 2001 Liam Davies (ldavies@agile.tv)
  *
  */
-#ifndef __ASM_MIPS_COBALT_H 
-#define __ASM_MIPS_COBALT_H 
+#ifndef __ASM_MIPS_COBALT_H
+#define __ASM_MIPS_COBALT_H
 
 /*
  * COBALT interrupt enable bits
@@ -46,6 +46,8 @@
 #define COBALT_PARALLEL_IRQ    5
 #define COBALT_FLOPPY_IRQ      6 /* needs to be consistent with floppy driver! */
 #define COBALT_SCSI_IRQ        7
+#define COBALT_SERIAL_IRQ      7
+#define COBALT_RAQ_SCSI_IRQ    4
 
 /*
  * PCI configuration space manifest constants.  These are wired into
@@ -63,32 +65,6 @@
 #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
diff -urN linux-2.4.20-pre6/include/asm-mips/cpu.h linux-2.4.20-pre7/include/asm-mips/cpu.h
--- linux-2.4.20-pre6/include/asm-mips/cpu.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/cpu.h	Thu Sep 12 20:01:49 2002
@@ -9,8 +9,8 @@
 
 #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 
+/* 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:
 
@@ -21,7 +21,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.  
+   spec.
 */
 
 #define PRID_COMP_LEGACY       0x000000
@@ -87,6 +87,12 @@
 #define PRID_REV_TX3912 	0x0010
 #define PRID_REV_TX3922 	0x0030
 #define PRID_REV_TX3927 	0x0040
+#define PRID_REV_VR4111		0x0050
+#define PRID_REV_VR4181		0x0050	/* Same as VR4111 */
+#define PRID_REV_VR4121		0x0060
+#define PRID_REV_VR4122		0x0070
+#define PRID_REV_VR4181A	0x0070	/* Same as VR4122 */
+#define PRID_REV_VR4131		0x0080
 
 /*
  * FPU implementation/revision register (CP1 control register 0).
@@ -100,6 +106,10 @@
 #define FPIR_IMP_NONE		0x0000
 
 #ifndef __ASSEMBLY__
+
+extern void cpu_probe(void);
+extern void cpu_report(void);
+
 /*
  * Capability and feature descriptor structure for MIPS CPU
  */
@@ -128,7 +138,8 @@
 	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
+	CPU_VR4111, CPU_VR4121, CPU_VR4122, CPU_VR4131, CPU_VR4181, CPU_VR4181A,
+	CPU_AU1100, CPU_LAST
 };
 
 #endif /* !__ASSEMBLY__ */
diff -urN linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5074.h linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5074.h
--- linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5074.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5074.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,38 @@
+/*
+ *  include/asm-mips/ddb5074.h -- NEC DDB Vrc-5074 definitions
+ *
+ *  Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ *                     Sony Software Development Center Europe (SDCE), Brussels
+ */
+
+#ifndef _ASM_DDB5XXX_DDB5074_H
+#define _ASM_DDB5XXX_DDB5074_H
+
+#include <asm/nile4.h>
+
+#define DDB_SDRAM_SIZE      0x04000000      /* 64MB */
+
+#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_PCI_CONFIG_BASE DDB_PCI_MEM_BASE
+#define DDB_PCI_CONFIG_SIZE DDB_PCI_MEM_SIZE
+
+#define NILE4_PCI_IO_BASE   0xa6000000
+#define NILE4_PCI_MEM_BASE  0xa8000000
+#define NILE4_PCI_CFG_BASE  NILE4_PCI_MEM_BASE
+#define DDB_PCI_IACK_BASE NILE4_PCI_IO_BASE
+
+#define NILE4_IRQ_BASE NUM_I8259_INTERRUPTS
+#define CPU_IRQ_BASE (NUM_NILE4_INTERRUPTS + NILE4_IRQ_BASE)
+#define CPU_NILE4_CASCADE 2
+
+extern void ddb5074_led_hex(int hex);
+extern void ddb5074_led_d2(int on);
+extern void ddb5074_led_d3(int on);
+
+extern void nile4_irq_setup(u32 base);
+#endif
diff -urN linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5476.h linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5476.h
--- linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5476.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5476.h	Thu Sep 12 20:01:49 2002
@@ -27,7 +27,7 @@
 #define	DDB_DCS2_BASE		0x05000000	/* flash 2 */
 #define	DDB_DCS2_SIZE		0x01000000	/* 16MB */
 
-#define DDB_PCI_IO_BASE		0x06000000      
+#define DDB_PCI_IO_BASE		0x06000000
 #define DDB_PCI_IO_SIZE		0x02000000      /* 32 MB */
 
 #define	DDB_PCI_MEM_BASE	0x08000000
@@ -70,7 +70,7 @@
  *  All PCI irq but INTC are active low.
  */
 
-/* 
+/*
  * irq number block assignment
  */
 
@@ -108,7 +108,7 @@
 /*
  * i2859 irq assignment
  */
-#define I8259_IRQ_RESERVED_0	0	
+#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  */
@@ -139,7 +139,7 @@
 /*
  * low-level irq functions
  */
-#ifndef _LANGUAGE_ASSEMBLY
+#ifndef __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);
@@ -154,4 +154,4 @@
 extern void nile4_clear_irq_mask(u32 mask);
 extern u8 nile4_i8259_iack(void);
 extern void nile4_dump_irq_status(void);        /* Debug */
-#endif
+#endif /* !__ASSEMBLY__ */
diff -urN linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5477.h linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5477.h
--- linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5477.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5477.h	Thu Sep 12 20:01:49 2002
@@ -216,6 +216,7 @@
 /*
  * DDB5477 specific functions
  */
+#ifndef __ASSEMBLY__
 extern void ddb5477_irq_setup(void);
 
 /* route irq to cpu int pin */
@@ -224,10 +225,110 @@
 /* low-level routine for enabling vrc5477 irq, bypassing high-level */
 extern void ll_vrc5477_irq_enable(int vrc5477_irq);
 extern void ll_vrc5477_irq_disable(int vrc5477_irq);
+#endif /* !__ASSEMBLY__ */
 
-/* 
+/* 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
+ *   . vrc5477 - 32 sources
+ *
+ *  They connected as follows:
+ *    all vrc5477 interrupts are routed to cpu IP2 (by software setting)
+ *    all i8359 are routed to INTC in vrc5477 (by hardware connection)
+ *
+ *  All VRC5477 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_VRC5477_IRQ		32
+
+#define	DDB_IRQ_BASE		0
+
+#define	I8259_IRQ_BASE		DDB_IRQ_BASE
+#define	VRC5477_IRQ_BASE	(I8259_IRQ_BASE + NUM_I8259_IRQ)
+#define	CPU_IRQ_BASE		(VRC5477_IRQ_BASE + NUM_VRC5477_IRQ)
+
+/*
+ * vrc5477 irq defs
+ */
+
+#define VRC5477_IRQ_CPCE	(0 + VRC5477_IRQ_BASE)	/* cpu parity error */
+#define VRC5477_IRQ_CNTD	(1 + VRC5477_IRQ_BASE)	/* cpu no target */
+#define VRC5477_IRQ_I2C		(2 + VRC5477_IRQ_BASE)	/* I2C */
+#define VRC5477_IRQ_DMA		(3 + VRC5477_IRQ_BASE)	/* DMA */
+#define VRC5477_IRQ_UART0	(4 + VRC5477_IRQ_BASE)
+#define VRC5477_IRQ_WDOG	(5 + VRC5477_IRQ_BASE)	/* watchdog timer */
+#define VRC5477_IRQ_SPT1	(6 + VRC5477_IRQ_BASE)    /* special purpose timer 1 */
+#define VRC5477_IRQ_LBRT	(7 + VRC5477_IRQ_BASE)	/* local bus read timeout */
+#define VRC5477_IRQ_INTA	(8 + VRC5477_IRQ_BASE)	/* PCI INT #A */
+#define VRC5477_IRQ_INTB	(9 + VRC5477_IRQ_BASE)	/* PCI INT #B */
+#define VRC5477_IRQ_INTC	(10 + VRC5477_IRQ_BASE)	/* PCI INT #C */
+#define VRC5477_IRQ_INTD	(11 + VRC5477_IRQ_BASE)	/* PCI INT #D */
+#define VRC5477_IRQ_INTE	(12 + VRC5477_IRQ_BASE)	/* PCI INT #E */
+#define VRC5477_IRQ_RESERVED_13	(13 + VRC5477_IRQ_BASE)	/* reserved  */
+#define VRC5477_IRQ_PCIS	(14 + VRC5477_IRQ_BASE)	/* PCI SERR #  */
+#define VRC5477_IRQ_PCI		(15 + VRC5477_IRQ_BASE)	/* PCI internal error */
+#define VRC5477_IRQ_IOPCI_INTA	(16 + VRC5477_IRQ_BASE)      /* USB-H */
+#define VRC5477_IRQ_IOPCI_INTB	(17 + VRC5477_IRQ_BASE)      /* USB-P */
+#define VRC5477_IRQ_IOPCI_INTC	(18 + VRC5477_IRQ_BASE)      /* AC97 */
+#define VRC5477_IRQ_IOPCI_INTD	(19 + VRC5477_IRQ_BASE)      /* Reserved */
+#define VRC5477_IRQ_UART1	(20 + VRC5477_IRQ_BASE)
+#define VRC5477_IRQ_SPT0	(21 + VRC5477_IRQ_BASE)      /* special purpose timer 0 */
+#define VRC5477_IRQ_GPT0	(22 + VRC5477_IRQ_BASE)      /* general purpose timer 0 */
+#define VRC5477_IRQ_GPT1	(23 + VRC5477_IRQ_BASE)      /* general purpose timer 1 */
+#define VRC5477_IRQ_GPT2	(24 + VRC5477_IRQ_BASE)      /* general purpose timer 2 */
+#define VRC5477_IRQ_GPT3	(25 + VRC5477_IRQ_BASE)      /* general purpose timer 3 */
+#define VRC5477_IRQ_GPIO	(26 + VRC5477_IRQ_BASE)
+#define VRC5477_IRQ_SIO0	(27 + VRC5477_IRQ_BASE)
+#define VRC5477_IRQ_SIO1        (28 + VRC5477_IRQ_BASE)
+#define VRC5477_IRQ_RESERVED_29 (29 + VRC5477_IRQ_BASE)      /* reserved */
+#define VRC5477_IRQ_IOPCISERR	(30 + VRC5477_IRQ_BASE)      /* IO PCI SERR # */
+#define VRC5477_IRQ_IOPCI	(31 + VRC5477_IRQ_BASE)
+
+/*
+ * i2859 irq assignment
+ */
+#define I8259_IRQ_RESERVED_0	(0 + I8259_IRQ_BASE)
+#define I8259_IRQ_KEYBOARD	(1 + I8259_IRQ_BASE)	/* M1543 default */
+#define I8259_IRQ_CASCADE	(2 + I8259_IRQ_BASE)
+#define I8259_IRQ_UART_B	(3 + I8259_IRQ_BASE)	/* M1543 default, may conflict with RTC according to schematic diagram  */
+#define I8259_IRQ_UART_A	(4 + I8259_IRQ_BASE)	/* M1543 default */
+#define I8259_IRQ_PARALLEL	(5 + I8259_IRQ_BASE)	/* M1543 default */
+#define I8259_IRQ_RESERVED_6	(6 + I8259_IRQ_BASE)
+#define I8259_IRQ_RESERVED_7	(7 + I8259_IRQ_BASE)
+#define I8259_IRQ_RTC		(8 + I8259_IRQ_BASE)	/* who set this? */
+#define I8259_IRQ_USB		(9 + I8259_IRQ_BASE)	/* ddb_setup */
+#define I8259_IRQ_PMU		(10 + I8259_IRQ_BASE)	/* ddb_setup */
+#define I8259_IRQ_RESERVED_11	(11 + I8259_IRQ_BASE)
+#define I8259_IRQ_RESERVED_12	(12 + I8259_IRQ_BASE)	/* m1543_irq_setup */
+#define I8259_IRQ_RESERVED_13	(13 + I8259_IRQ_BASE)
+#define I8259_IRQ_HDC1		(14 + I8259_IRQ_BASE)	/* default and ddb_setup */
+#define I8259_IRQ_HDC2		(15 + I8259_IRQ_BASE)	/* default */
+
+
+/*
+ * misc
+ */
+#define	VRC5477_I8259_CASCADE	(VRC5477_IRQ_INTC - VRC5477_IRQ_BASE)
+#define	CPU_VRC5477_CASCADE	2
+
+/*
  * debug routines
  */
+#ifndef __ASSEMBLY__
 #if defined(CONFIG_DEBUG)
 extern void vrc5477_show_pdar_regs(void);
 extern void vrc5477_show_pci_regs(void);
@@ -240,5 +341,6 @@
  * RAM size
  */
 extern int board_ram_size;
+#endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_DDB5XXX_DDB5477_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5xxx.h linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5xxx.h
--- linux-2.4.20-pre6/include/asm-mips/ddb5xxx/ddb5xxx.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/ddb5xxx/ddb5xxx.h	Thu Sep 12 20:01:49 2002
@@ -31,7 +31,7 @@
  *
  *	uPD31577(VRC5477) VR5432-SDRAM/PCI Bridge (Luke)
  *	Preliminary Specification Decoment, Rev 1.1, 27 Dec, 2000
- *  
+ *
  */
 
 
@@ -174,8 +174,13 @@
 
 static inline void ddb_sync(void)
 {
+/* The DDB5074 doesn't seem to like these accesses. They kill the board on
+ * interrupt load
+ */
+#ifndef CONFIG_DDB5074
     volatile u32 *p = (volatile u32 *)0xbfc00000;
     (void)(*p);
+#endif
 }
 
 static inline void ddb_out32(u32 offset, u32 val)
@@ -222,9 +227,9 @@
  *  Physical Device Address Registers
  */
 
-extern u32 
+extern u32
 ddb_calc_pdar(u32 phys, u32 size, int width, int on_memory_bus, int pci_visible);
-extern void 
+extern void
 ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width,
 	     int on_memory_bus, int pci_visible);
 
diff -urN linux-2.4.20-pre6/include/asm-mips/debug.h linux-2.4.20-pre7/include/asm-mips/debug.h
--- linux-2.4.20-pre6/include/asm-mips/debug.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/debug.h	Thu Sep 12 20:01:49 2002
@@ -17,7 +17,7 @@
 #include <linux/config.h>
 
 /*
- * run-time macros for catching spurious errors.  Eable CONFIG_DEBUG in 
+ * 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!!!
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/interrupts.h linux-2.4.20-pre7/include/asm-mips/dec/interrupts.h
--- linux-2.4.20-pre6/include/asm-mips/dec/interrupts.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/interrupts.h	Thu Sep 12 20:01:49 2002
@@ -1,4 +1,4 @@
-/*  
+/*
  * Miscellaneous definitions used to initialise the interrupt vector table
  * with the machine-specific interrupt routines.
  *
@@ -11,8 +11,8 @@
  * Copyright (C) 2001, 2002  Maciej W. Rozycki
  */
 
-#ifndef __ASM_DEC_INTERRUPTS_H 
-#define __ASM_DEC_INTERRUPTS_H 
+#ifndef __ASM_DEC_INTERRUPTS_H
+#define __ASM_DEC_INTERRUPTS_H
 
 #include <asm/mipsregs.h>
 
@@ -122,4 +122,4 @@
 
 #endif /* __ASSEMBLY__ */
 
-#endif 
+#endif
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/ioasic_addrs.h linux-2.4.20-pre7/include/asm-mips/dec/ioasic_addrs.h
--- linux-2.4.20-pre6/include/asm-mips/dec/ioasic_addrs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/ioasic_addrs.h	Thu Sep 12 20:01:49 2002
@@ -15,27 +15,27 @@
 #ifndef IOASIC_ADDRS_H
 #define IOASIC_ADDRS_H
 
-#define CHUNK_SIZE 0x00040000
+#define IOASIC_SLOT_SIZE 0x00040000
 
-#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? */
+#define SYSTEM_ROM 	(0*IOASIC_SLOT_SIZE)	/* board ROM */
+#define IOCTL 		(1*IOASIC_SLOT_SIZE)	/* I/O ASIC */
+#define ESAR 		(2*IOASIC_SLOT_SIZE)	/* LANCE MAC address chip */
+#define LANCE 		(3*IOASIC_SLOT_SIZE)	/* LANCE Ethernet */
+#define SCC0 		(4*IOASIC_SLOT_SIZE)	/* SCC #0 */
+#define VDAC_HI		(5*IOASIC_SLOT_SIZE)	/* VDAC (maxine) */
+#define SCC1 		(6*IOASIC_SLOT_SIZE)	/* SCC #1 (3min, 3max+) */
+#define VDAC_LO		(7*IOASIC_SLOT_SIZE)	/* VDAC (maxine) */
+#define TOY 		(8*IOASIC_SLOT_SIZE)	/* RTC */
+#define ISDN 		(9*IOASIC_SLOT_SIZE)	/* ISDN (maxine) */
+#define ERRADDR		(9*IOASIC_SLOT_SIZE)	/* bus error address (3max+) */
+#define CHKSYN 		(10*IOASIC_SLOT_SIZE)	/* ECC syndrome (3max+) */
+#define ACCESS_BUS	(10*IOASIC_SLOT_SIZE)	/* Access.Bus (maxine) */
+#define MCR 		(11*IOASIC_SLOT_SIZE)	/* memory control (3max+) */
+#define FLOPPY 		(11*IOASIC_SLOT_SIZE)	/* FDC (maxine) */
+#define SCSI 		(12*IOASIC_SLOT_SIZE)	/* ASC SCSI */
+#define FLOPPY_DMA 	(13*IOASIC_SLOT_SIZE)	/* FDC DMA (maxine) */
+#define SCSI_DMA 	(14*IOASIC_SLOT_SIZE)	/* ??? */
+#define RESERVED_4 	(15*IOASIC_SLOT_SIZE)	/* unused? */
 
 /*
  * Offsets for IOCTL registers (relative to (system_base + IOCTL))
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/ioasic_ints.h linux-2.4.20-pre7/include/asm-mips/dec/ioasic_ints.h
--- linux-2.4.20-pre6/include/asm-mips/dec/ioasic_ints.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/ioasic_ints.h	Thu Sep 12 20:01:49 2002
@@ -19,7 +19,7 @@
 #ifndef __ASM_DEC_IOASIC_INTS_H
 #define __ASM_DEC_IOASIC_INTS_H
 
-/* 
+/*
  * 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
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn01.h linux-2.4.20-pre7/include/asm-mips/dec/kn01.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn01.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn01.h	Thu Sep 12 20:01:49 2002
@@ -10,14 +10,15 @@
  * are by courtesy of Chris Fraser.
  * Copyright (C) 2002  Maciej W. Rozycki
  */
-#ifndef __ASM_MIPS_DEC_KN01_H 
-#define __ASM_MIPS_DEC_KN01_H 
+#ifndef __ASM_MIPS_DEC_KN01_H
+#define __ASM_MIPS_DEC_KN01_H
 
 #include <asm/addrspace.h>
 
 /*
  * Some port addresses...
  */
+#define KN01_SLOT_SIZE	0x01000000
 
 #define KN01_LANCE_BASE (KSEG1ADDR(0x18000000)) /* 0xB8000000 */
 #define KN01_DZ11_BASE	(KSEG1ADDR(0x1c000000)) /* 0xBC000000 */
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn02.h linux-2.4.20-pre7/include/asm-mips/dec/kn02.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn02.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn02.h	Thu Sep 12 20:01:49 2002
@@ -10,8 +10,8 @@
  * 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 __ASM_MIPS_DEC_KN02_H
+#define __ASM_MIPS_DEC_KN02_H
 
 #ifndef __ASSEMBLY__
 #include <linux/spinlock.h>
@@ -29,6 +29,8 @@
 /*
  * Some port addresses...
  */
+#define KN02_SLOT_SIZE	0x00080000
+
 #define KN02_RTC_BASE	KSEG1ADDR(0x1fe80000)
 #define KN02_DZ11_BASE	KSEG1ADDR(0x1fe00000)
 
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn02ba.h linux-2.4.20-pre7/include/asm-mips/dec/kn02ba.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn02ba.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn02ba.h	Thu Sep 12 20:01:49 2002
@@ -10,8 +10,8 @@
  *	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 
+#ifndef __ASM_MIPS_DEC_KN02BA_H
+#define __ASM_MIPS_DEC_KN02BA_H
 
 #include <asm/dec/kn02xa.h>		/* For common definitions. */
 
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn02ca.h linux-2.4.20-pre7/include/asm-mips/dec/kn02ca.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn02ca.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn02ca.h	Thu Sep 12 20:01:49 2002
@@ -10,8 +10,8 @@
  *	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 
+#ifndef __ASM_MIPS_DEC_KN02CA_H
+#define __ASM_MIPS_DEC_KN02CA_H
 
 #include <asm/dec/kn02xa.h>		/* For common definitions. */
 
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn02xa.h linux-2.4.20-pre7/include/asm-mips/dec/kn02xa.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn02xa.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn02xa.h	Thu Sep 12 20:01:49 2002
@@ -14,8 +14,8 @@
  * 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.
  */
-#ifndef __ASM_MIPS_DEC_KN02XA_H 
-#define __ASM_MIPS_DEC_KN02XA_H 
+#ifndef __ASM_MIPS_DEC_KN02XA_H
+#define __ASM_MIPS_DEC_KN02XA_H
 
 #include <asm/addrspace.h>
 
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn03.h linux-2.4.20-pre7/include/asm-mips/dec/kn03.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn03.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn03.h	Thu Sep 12 20:01:49 2002
@@ -15,8 +15,8 @@
  * 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.
  */
-#ifndef __ASM_MIPS_DEC_KN03_H 
-#define __ASM_MIPS_DEC_KN03_H 
+#ifndef __ASM_MIPS_DEC_KN03_H
+#define __ASM_MIPS_DEC_KN03_H
 
 #include <asm/addrspace.h>
 
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn05.h linux-2.4.20-pre7/include/asm-mips/dec/kn05.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn05.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn05.h	Thu Sep 12 20:01:49 2002
@@ -27,22 +27,22 @@
  * 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? */
+#define KN05_MB_ROM	(16*IOASIC_SLOT_SIZE)	/* KN05 card ROM */
+#define KN05_IOCTL	(17*IOASIC_SLOT_SIZE)	/* I/O ASIC */
+#define KN05_ESAR	(18*IOASIC_SLOT_SIZE)	/* LANCE MAC address chip */
+#define KN05_LANCE	(19*IOASIC_SLOT_SIZE)	/* LANCE Ethernet */
+#define KN05_MB_INT	(20*IOASIC_SLOT_SIZE)	/* MB interrupt register? */
+#define KN05_MB_UNKN_0	(21*IOASIC_SLOT_SIZE)	/* MB unknown register */
+#define KN05_MB_UNKN_1	(22*IOASIC_SLOT_SIZE)	/* MB unknown register */
+#define KN05_MB_CSR	(23*IOASIC_SLOT_SIZE)	/* MB control & status */
+#define KN05_RESERVED_0	(24*IOASIC_SLOT_SIZE)	/* unused? */
+#define KN05_RESERVED_1	(25*IOASIC_SLOT_SIZE)	/* unused? */
+#define KN05_RESERVED_2	(26*IOASIC_SLOT_SIZE)	/* unused? */
+#define KN05_RESERVED_3	(27*IOASIC_SLOT_SIZE)	/* unused? */
+#define KN05_SCSI	(28*IOASIC_SLOT_SIZE)	/* ASC SCSI */
+#define KN05_RESERVED_4	(29*IOASIC_SLOT_SIZE)	/* unused? */
+#define KN05_RESERVED_5	(30*IOASIC_SLOT_SIZE)	/* unused? */
+#define KN05_RESERVED_6	(31*IOASIC_SLOT_SIZE)	/* unused? */
 
 /*
  * Bits for the MB interrupt (?) register.
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/kn230.h linux-2.4.20-pre7/include/asm-mips/dec/kn230.h
--- linux-2.4.20-pre6/include/asm-mips/dec/kn230.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/kn230.h	Thu Sep 12 20:01:49 2002
@@ -10,8 +10,8 @@
  *	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 
+#ifndef __ASM_MIPS_DEC_KN230_H
+#define __ASM_MIPS_DEC_KN230_H
 
 /*
  * CPU interrupt bits.
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/machtype.h linux-2.4.20-pre7/include/asm-mips/dec/machtype.h
--- linux-2.4.20-pre6/include/asm-mips/dec/machtype.h	Thu Feb 24 22:52:30 2000
+++ linux-2.4.20-pre7/include/asm-mips/dec/machtype.h	Thu Sep 12 20:01:49 2002
@@ -8,8 +8,8 @@
  * Copyright (c) 1998, 2000 Harald Koerfgen
  */
 
-#ifndef __ASM_DEC_MACHTYPE_H 
-#define __ASM_DEC_MACHTYPE_H 
+#ifndef __ASM_DEC_MACHTYPE_H
+#define __ASM_DEC_MACHTYPE_H
 
 #include <asm/bootinfo.h>
 
@@ -17,7 +17,7 @@
 			 mips_machtype == MACH_DS5000_1XX || \
 			 mips_machtype == MACH_DS5000_XX  || \
 			 mips_machtype == MACH_DS5000_2X0)
-		      
+
 #define IOASIC		(mips_machtype == MACH_DS5000_1XX || \
 			 mips_machtype == MACH_DS5000_XX  || \
 			 mips_machtype == MACH_DS5000_2X0)
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/rtc-dec.h linux-2.4.20-pre7/include/asm-mips/dec/rtc-dec.h
--- linux-2.4.20-pre6/include/asm-mips/dec/rtc-dec.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/dec/rtc-dec.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,32 @@
+/*
+ *	include/asm-mips/dec/rtc-dec.h
+ *
+ *	RTC definitions for DECstation style attached Dallas DS1287 chip.
+ *
+ *	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_RTC_DEC_H
+#define __ASM_MIPS_DEC_RTC_DEC_H
+
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+
+extern volatile u8 *dec_rtc_base;
+extern unsigned long dec_kn_slot_size;
+
+extern struct rtc_ops dec_rtc_ops;
+
+#define RTC_PORT(x)	CPHYSADDR(dec_rtc_base)
+#define RTC_IO_EXTENT	dec_kn_slot_size
+#define RTC_IOMAPPED	0
+#define RTC_IRQ		0
+
+#define RTC_DEC_YEAR	0x3f	/* Where we store the real year on DECs.  */
+
+#endif /* __ASM_MIPS_DEC_RTC_DEC_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/tc.h linux-2.4.20-pre7/include/asm-mips/dec/tc.h
--- linux-2.4.20-pre6/include/asm-mips/dec/tc.h	Fri Jun 25 17:37:53 1999
+++ linux-2.4.20-pre7/include/asm-mips/dec/tc.h	Thu Sep 12 20:01:49 2002
@@ -28,7 +28,7 @@
  */
 extern void release_tc_card(int);
 /*
- * Return base address of card in slot 
+ * Return base address of card in slot
  */
 extern unsigned long get_tc_base_addr(int);
 /*
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/tcinfo.h linux-2.4.20-pre7/include/asm-mips/dec/tcinfo.h
--- linux-2.4.20-pre6/include/asm-mips/dec/tcinfo.h	Fri Jun 25 17:37:53 1999
+++ linux-2.4.20-pre7/include/asm-mips/dec/tcinfo.h	Thu Sep 12 20:01:49 2002
@@ -1,4 +1,4 @@
-/* 
+/*
  * Various TURBOchannel related stuff
  *
  * This file is subject to the terms and conditions of the GNU General Public
diff -urN linux-2.4.20-pre6/include/asm-mips/dec/tcmodule.h linux-2.4.20-pre7/include/asm-mips/dec/tcmodule.h
--- linux-2.4.20-pre6/include/asm-mips/dec/tcmodule.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dec/tcmodule.h	Thu Sep 12 20:01:49 2002
@@ -1,4 +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.
@@ -17,7 +17,7 @@
  */
 #ifndef __ASM_DEC_TCMODULE_H
 #define __ASM_DEC_TCMODULE_H
- 
+
 #define OLDCARD 0x3c0000
 #define NEWCARD 0x000000
 
diff -urN linux-2.4.20-pre6/include/asm-mips/delay.h linux-2.4.20-pre7/include/asm-mips/delay.h
--- linux-2.4.20-pre6/include/asm-mips/delay.h	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/include/asm-mips/delay.h	Thu Sep 12 20:01:49 2002
@@ -10,6 +10,7 @@
 #define _ASM_DELAY_H
 
 #include <linux/config.h>
+#include <linux/param.h>
 
 extern unsigned long loops_per_jiffy;
 
@@ -39,7 +40,11 @@
 {
 	unsigned long lo;
 
+#if (HZ == 100)
 	usecs *= 0x00068db8;		/* 2**32 / (1000000 / HZ) */
+#elif (HZ == 128)
+	usecs *= 0x0008637b;		/* 2**32 / (1000000 / HZ) */
+#endif
 	__asm__("multu\t%2,%3"
 		:"=h" (usecs), "=l" (lo)
 		:"r" (usecs),"r" (lpj));
diff -urN linux-2.4.20-pre6/include/asm-mips/dma.h linux-2.4.20-pre7/include/asm-mips/dma.h
--- linux-2.4.20-pre6/include/asm-mips/dma.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/dma.h	Thu Sep 12 20:01:49 2002
@@ -43,7 +43,7 @@
  *  - 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
  *
- * DMA transfers are limited to the lower 16MB of _physical_ memory.  
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.
  * Note that addresses loaded into registers must be _physical_ addresses,
  * not logical addresses (which may differ if paging is active).
  *
@@ -53,7 +53,7 @@
  *    |  ...  |   |  ... |   |  ... |
  *    |  ...  |   |  ... |   |  ... |
  *    |  ...  |   |  ... |   |  ... |
- *   P7  ...  P0  A7 ... A0  A7 ... A0   
+ *   P7  ...  P0  A7 ... A0  A7 ... A0
  * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
  *
  *  Address mapping for channels 5-7:
@@ -62,7 +62,7 @@
  *    |  ...  |   \   \   ... \  \  \  ... \  \
  *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
  *    |  ...  |     \   \   ... \  \  \  ... \
- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+ *   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
@@ -71,7 +71,7 @@
  *
  * 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. 
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation.
  *
  */
 
@@ -83,7 +83,13 @@
  * Deskstations or Acer PICA but not the much more versatile DMA logic used
  * for the local devices on Acer PICA or Magnums.
  */
+#ifdef CONFIG_SGI_IP22
+/* Horrible hack to have a correct DMA window on IP22 */
+#include <asm/sgi/sgimc.h>
+#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000)
+#else
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + 0x01000000)
+#endif
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
@@ -142,6 +148,7 @@
 #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;
 
@@ -286,7 +293,7 @@
 
 	count = 1 + dma_inb(io_port);
 	count += dma_inb(io_port) << 8;
-	
+
 	return (dmanr<=3)? count : (count<<1);
 }
 
diff -urN linux-2.4.20-pre6/include/asm-mips/elf.h linux-2.4.20-pre7/include/asm-mips/elf.h
--- linux-2.4.20-pre6/include/asm-mips/elf.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/elf.h	Thu Sep 12 20:01:49 2002
@@ -16,10 +16,11 @@
 #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.  */
+#define EF_MIPS_ARCH_32     0x50000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64     0x60000000  /* MIPS64 code.  */
+/* The ABI of a file. */
+#define EF_MIPS_ABI_O32     0x00001000  /* O32 ABI.  */
+#define EF_MIPS_ABI_O64     0x00002000  /* O32 extended for 64 bit.  */
 
 typedef unsigned long elf_greg_t;
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
@@ -37,10 +38,12 @@
 									\
 	if (__h->e_machine != EM_MIPS)					\
 		__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))      	\
+	if (__h->e_ident[EI_CLASS] != ELFCLASS32)			\
+		__res = 0;						\
+	if ((__h->e_flags & EF_MIPS_ABI2) != 0)				\
+		__res = 0;						\
+	if (((__h->e_flags & EF_MIPS_ABI) != 0) &&			\
+	    ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))		\
 		__res = 0;						\
 									\
 	__res;								\
diff -urN linux-2.4.20-pre6/include/asm-mips/fcntl.h linux-2.4.20-pre7/include/asm-mips/fcntl.h
--- linux-2.4.20-pre6/include/asm-mips/fcntl.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/fcntl.h	Thu Sep 12 20:01:49 2002
@@ -65,7 +65,7 @@
 /* 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		XXXXXXXXXXXXXXXXXX
+#define LOCK_NB		4	/* or'd with one of the above to prevent
 				   blocking */
 #define LOCK_UN		8	/* remove lock */
 
@@ -74,14 +74,21 @@
 #define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
 #define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
 
+/*
+ * The flavours of struct flock.  "struct flock" is the ABI compliant
+ * variant.  Finally struct flock64 is the LFS variant of struct flock.  As
+ * a historic accident and inconsistence with the ABI definition it doesn't
+ * contain all the same fields as struct flock.
+ */
+
 typedef struct flock {
-	short l_type;
-	short l_whence;
+	short	l_type;
+	short	l_whence;
 	__kernel_off_t l_start;
 	__kernel_off_t l_len;
-	long  l_sysid;			/* ABI junk, unused on Linux */
+	long	l_sysid;
 	__kernel_pid_t l_pid;
-	long  pad[4];			/* ABI junk, unused on Linux */
+	long	pad[4];
 } flock_t;
 
 typedef struct flock64 {
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/ev64120.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/ev64120.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/ev64120.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/ev64120.h	Thu Sep 12 20:01:49 2002
@@ -15,7 +15,7 @@
  */
 #define GT64120_BASE    (KSEG1ADDR(0x14000000))
 #define MIPS_GT_BASE    GT64120_BASE
- 
+
 /*
  *   PCI Bus allocation
  */
@@ -23,12 +23,12 @@
 #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          
+#define GT_ISA_IO_BASE     PCI_IO_BASE
 
 /*
  *   Duart I/O ports.
  */
-#define EV64120_COM1_BASE_ADDR  (0x1d000000 + 0x20) 
+#define EV64120_COM1_BASE_ADDR  (0x1d000000 + 0x20)
 #define EV64120_COM2_BASE_ADDR  (0x1d000000 + 0x00)
 
 
@@ -46,7 +46,7 @@
 
 
 /*
- * Because of an error/peculiarity in the Galileo chip, we need to swap the 
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the
  * bytes when running bigendian.
  */
 
@@ -54,6 +54,6 @@
              *(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 -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/ev96100.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/ev96100.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/ev96100.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/ev96100.h	Thu Sep 12 20:01:49 2002
@@ -11,7 +11,7 @@
  */
 #define GT64120_BASE    (KSEG1ADDR(0x14000000))
 #define MIPS_GT_BASE    GT64120_BASE
- 
+
 /*
  *   PCI Bus allocation
  */
@@ -19,12 +19,12 @@
 #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          
+#define GT_ISA_IO_BASE     PCI_IO_BASE
 
 /*
  *   Duart I/O ports.
  */
-#define EV96100_COM1_BASE_ADDR  (0xBD000000 + 0x20) 
+#define EV96100_COM1_BASE_ADDR  (0xBD000000 + 0x20)
 #define EV96100_COM2_BASE_ADDR  (0xBD000000 + 0x00)
 
 
@@ -42,7 +42,7 @@
 
 
 /*
- * Because of an error/peculiarity in the Galileo chip, we need to swap the 
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the
  * bytes when running bigendian.
  */
 
@@ -50,6 +50,6 @@
              *(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 -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/ev96100int.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/ev96100int.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/ev96100int.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/ev96100int.h	Thu Sep 12 20:01:49 2002
@@ -4,7 +4,7 @@
 #ifndef _MIPS_EV96100INT_H
 #define _MIPS_EV96100INT_H
 
-#define EV96100INT_UART_0    6     /* IP 6 */     
+#define EV96100INT_UART_0    6     /* IP 6 */
 #define EV96100INT_TIMER     7     /* IP 7 */
 
 extern void ev96100int_init(void);
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/cntmr.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/cntmr.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/cntmr.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/cntmr.h	Thu Sep 12 20:01:49 2002
@@ -2,7 +2,7 @@
 
 /* Copyright - Galileo technology */
 
-#ifndef __INCtimerCounterDrvh 
+#ifndef __INCtimerCounterDrvh
 #define __INCtimerCounterDrvh
 
 /* includes */
@@ -31,12 +31,12 @@
 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    cntTmrLoad(unsigned int countNum, unsigned int value);
 bool    cntTmrSetMode(CNTMR_NUM countNum, CNT_TMR_OP_MODES opMode);
-bool    cntTmrEnable(CNTMR_NUM countNum);  
+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    cntTmrDisable(CNTMR_NUM countNum);
 unsigned int    cntTmrRead(CNTMR_NUM countNum);
 
 #endif /* __INCtimerCounterDrvh */
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/core.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/core.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/core.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/core.h	Thu Sep 12 20:01:49 2002
@@ -4,7 +4,7 @@
  *
  * Copyright Galileo Technology.
  */
-#ifndef __INCcoreh 
+#ifndef __INCcoreh
 #define __INCcoreh
 
 #include <linux/types.h>
@@ -78,7 +78,7 @@
 typedef enum _bool{false,true} bool;
 
 #ifndef NULL
-#define NULL 0                                  
+#define NULL 0
 #endif
 
 /* The two following defines are according to MIPS architecture. */
@@ -111,7 +111,7 @@
 /* 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)
 
@@ -158,8 +158,8 @@
 	(*((u32 *)((address) | MIPS_CACHEABLE)))
 
 /*
- * SET_REG_BITS(regOffset,bits) - 
- * gets register offset and bits: a 32bit value. It set to logic '1' in the  
+ * 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.
@@ -170,7 +170,7 @@
 
 /*
  * RESET_REG_BITS(regOffset,bits) -
- * gets register offset and bits: a 32bit value. It set to logic '0' in the  
+ * 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.
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/dma.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/dma.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/dma.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/dma.h	Thu Sep 12 20:01:49 2002
@@ -2,7 +2,7 @@
 
 /* Copyright Galileo Technology. */
 
-#ifndef __INCdmah 
+#ifndef __INCdmah
 #define __INCdmah
 
 /* includes */
@@ -55,11 +55,11 @@
 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 enum prioOpt{RETURN_BUS,KEEP_BUS} PRIO_OPT;
 
 typedef struct dmaRecored
 {
-    unsigned int    ByteCnt;                                            
+    unsigned int    ByteCnt;
     unsigned int    SrcAdd;
     unsigned int    DestAdd;
     unsigned int    NextRecPtr;
@@ -74,7 +74,7 @@
 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, 
+bool    changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23,
                           PRIO_GROUP prioGrp, PRIO_OPT prioOpt);
 
 #endif /* __INCdmah */
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/eeprom_param.h	Thu Sep 12 20:01:49 2002
@@ -32,12 +32,12 @@
 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];
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/flashdrv.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/flashdrv.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/flashdrv.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/flashdrv.h	Thu Sep 12 20:01:49 2002
@@ -2,7 +2,7 @@
 
 /* Copyright Galileo Technology. */
 
-#ifndef __INCflashdrvh 
+#ifndef __INCflashdrvh
 #define __INCflashdrvh
 
 /* includes */
@@ -11,7 +11,7 @@
 
 /* defines */
 
-/* Supported Flash Manufactures */ 
+/* Supported Flash Manufactures */
 
 #define AMD_FLASH       0x01
 #define ST_FLASH        0x20
@@ -21,7 +21,7 @@
 /* Supported Flash Devices */
 
 /* AMD Devices */
-#define AM29F400BT      0x2223    
+#define AM29F400BT      0x2223
 #define AM29F400BB      0x22AB
 #define AM29LV800BT     0x22DA
 #define AM29LV400BT     0x22B9
@@ -34,12 +34,12 @@
 #define I28F640J3A      0x17
 #define I28F128J3A      0x18
 #define I28F320B3_B     0x8897
-#define I28F320B3_T     0x8896 
+#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 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
@@ -47,11 +47,11 @@
 #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  
+/* 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.*/
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/i2o.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/i2o.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/i2o.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/i2o.h	Thu Sep 12 20:01:49 2002
@@ -5,11 +5,11 @@
 #ifndef __INCi2oh
 #define __INCi2oh
 
-/* includes */            
-            
+/* includes */
+
 #include "core.h"
 
-/* typedefs */           
+/* 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,\
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/pci.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/pci.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/evb64120A/pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/evb64120A/pci.h	Thu Sep 12 20:01:49 2002
@@ -29,7 +29,7 @@
 
 #define PCI0_MEMORY_ENABLE(deviceNumber) pci0WriteConfigReg(                  \
           PCI_0STATUS_AND_COMMAND,deviceNumber,MEMORY_ENABLE |                \
-          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )           
+          pci0ReadConfigReg(PCI_0STATUS_AND_COMMAND,deviceNumber) )
 
 #define PCI1_MEMORY_ENABLE(deviceNumber) pci1WriteConfigReg(                  \
           PCI_0STATUS_AND_COMMAND,deviceNumber,MEMORY_ENABLE |                \
@@ -59,9 +59,9 @@
           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 	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
@@ -70,7 +70,7 @@
 #define     BAR3                    0x1c
 #define     BAR4                    0x20
 #define     BAR5                    0x24
-   
+
 
 /* typedefs */
 
@@ -78,7 +78,7 @@
 {
     char            type[20];
     unsigned int    deviceNum;
-    unsigned int    venID;                                            
+    unsigned int    venID;
     unsigned int    deviceID;
     unsigned int    bar0Base;
     unsigned int    bar0Size;
diff -urN linux-2.4.20-pre6/include/asm-mips/galileo-boards/gt96100.h linux-2.4.20-pre7/include/asm-mips/galileo-boards/gt96100.h
--- linux-2.4.20-pre6/include/asm-mips/galileo-boards/gt96100.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/galileo-boards/gt96100.h	Thu Sep 12 20:01:49 2002
@@ -21,7 +21,7 @@
  * ########################################################################
  *
  * Register offsets of the MIPS GT96100 Advanced Communication Controller.
- * 
+ *
  */
 #ifndef _GT96100_H
 #define _GT96100_H
@@ -46,24 +46,24 @@
 #define GT96100_CPU_INTERF_CONFIG 0x000000
 
 /* Ethernet Ports */
-#define GT96100_ETH_PHY_ADDR_REG             0x080800 
-#define GT96100_ETH_SMI_REG                  0x080810 
+#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_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
@@ -74,142 +74,142 @@
 #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 
+#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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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
@@ -221,23 +221,23 @@
 #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_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_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_LOW   0x018A00
 #define GT96100_MPSC3_MAIN_CONFIG_HIGH  0x018A04
-#define GT96100_MPSC3_PROTOCOL_CONFIG   0x018A08 
+#define GT96100_MPSC3_PROTOCOL_CONFIG   0x018A08
 #define GT96100_MPSC_CHAN3_REG1         0x018A0C
 #define GT96100_MPSC_CHAN3_REG2         0x018A10
 #define GT96100_MPSC_CHAN3_REG3         0x018A14
@@ -249,23 +249,23 @@
 #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_LOW   0x020A00
 #define GT96100_MPSC4_MAIN_CONFIG_HIGH  0x020A04
-#define GT96100_MPSC4_PROTOCOL_CONFIG   0x020A08 
+#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_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_LOW   0x028A00
 #define GT96100_MPSC5_MAIN_CONFIG_HIGH  0x028A04
-#define GT96100_MPSC5_PROTOCOL_CONFIG   0x028A08 
+#define GT96100_MPSC5_PROTOCOL_CONFIG   0x028A08
 #define GT96100_MPSC_CHAN5_REG1         0x028A0C
 #define GT96100_MPSC_CHAN5_REG2         0x028A10
 #define GT96100_MPSC_CHAN5_REG3         0x028A14
@@ -277,9 +277,9 @@
 #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_LOW   0x030A00
 #define GT96100_MPSC6_MAIN_CONFIG_HIGH  0x030A04
-#define GT96100_MPSC6_PROTOCOL_CONFIG   0x030A08 
+#define GT96100_MPSC6_PROTOCOL_CONFIG   0x030A08
 #define GT96100_MPSC_CHAN6_REG1         0x030A0C
 #define GT96100_MPSC_CHAN6_REG2         0x030A10
 #define GT96100_MPSC_CHAN6_REG3         0x030A14
@@ -291,9 +291,9 @@
 #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_LOW   0x038A00
 #define GT96100_MPSC7_MAIN_CONFIG_HIGH  0x038A04
-#define GT96100_MPSC7_PROTOCOL_CONFIG   0x038A08 
+#define GT96100_MPSC7_PROTOCOL_CONFIG   0x038A08
 #define GT96100_MPSC_CHAN7_REG1         0x038A0C
 #define GT96100_MPSC_CHAN7_REG2         0x038A10
 #define GT96100_MPSC_CHAN7_REG3         0x038A14
@@ -308,14 +308,14 @@
 /*  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_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_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
@@ -323,14 +323,14 @@
 #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_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
@@ -339,7 +339,7 @@
 #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_BLK1_BASE  0x021B00
 #define GT96100_FLTDM2_TDPR2_BLK2_BASE  0x022B00
 #define GT96100_FLTDM2_TDPR2_BLK3_BASE  0x023B00
 #define GT96100_FLTDM2_RDPR2_BLK0_BASE  0x024B00
@@ -369,46 +369,46 @@
 #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 
+#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 
+#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 
+#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 
+#define GT96100_WD_CONFIG   0x101A80
+#define GT96100_WD_VALUE    0x101A84
 /* Communication Unit Arbiter  */
 #define GT96100_COMM_UNIT_ARBTR_CONFIG 0x101AC0
 /*  PCI Arbiters  */
diff -urN linux-2.4.20-pre6/include/asm-mips/gdb-stub.h linux-2.4.20-pre7/include/asm-mips/gdb-stub.h
--- linux-2.4.20-pre6/include/asm-mips/gdb-stub.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/gdb-stub.h	Thu Sep 12 20:01:49 2002
@@ -57,7 +57,7 @@
 #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
  */
@@ -180,7 +180,7 @@
 	 */
 	long	frame_ptr;
 	long    dummy;		/* unused */
-	
+
 	/*
 	 * saved cp0 registers
 	 */
diff -urN linux-2.4.20-pre6/include/asm-mips/gfx.h linux-2.4.20-pre7/include/asm-mips/gfx.h
--- linux-2.4.20-pre6/include/asm-mips/gfx.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/gfx.h	Thu Sep 12 20:01:49 2002
@@ -6,7 +6,7 @@
  * This is the user-visible SGI GFX interface.
  *
  * This must be used verbatim into the GNU libc.  It does not include
- * any kernel-only bits on it.  
+ * any kernel-only bits on it.
  *
  * miguel@nuclecu.unam.mx
  */
diff -urN linux-2.4.20-pre6/include/asm-mips/gt64120.h linux-2.4.20-pre7/include/asm-mips/gt64120.h
--- linux-2.4.20-pre6/include/asm-mips/gt64120.h	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/include/asm-mips/gt64120.h	Thu Sep 12 20:01:49 2002
@@ -60,7 +60,7 @@
 #define GT_PCI1M0REMAP_OFS	0x110
 #define GT_PCI1M1REMAP_OFS	0x118
 
-#define GT_SCS0LD_OFS		0x400	
+#define GT_SCS0LD_OFS		0x400
 #define GT_SCS0HD_OFS		0x404
 #define GT_SCS1LD_OFS		0x408
 #define GT_SCS1HD_OFS		0x40c
@@ -324,7 +324,7 @@
 #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
diff -urN linux-2.4.20-pre6/include/asm-mips/highmem.h linux-2.4.20-pre7/include/asm-mips/highmem.h
--- linux-2.4.20-pre6/include/asm-mips/highmem.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/highmem.h	Thu Sep 12 20:01:49 2002
@@ -8,7 +8,7 @@
  *		      Gerhard.Wichert@pdb.siemens.de
  *
  *
- * Redesigned the x86 32-bit VM architecture to deal with 
+ * 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.
  *
diff -urN linux-2.4.20-pre6/include/asm-mips/io.h linux-2.4.20-pre7/include/asm-mips/io.h
--- linux-2.4.20-pre6/include/asm-mips/io.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/io.h	Thu Sep 12 20:01:49 2002
@@ -18,6 +18,16 @@
 #include <asm/pgtable-bits.h>
 #include <asm/byteorder.h>
 
+#ifdef CONFIG_SGI_IP27
+extern unsigned long bus_to_baddr[256];
+
+#define bus_to_baddr(hwdev, addr) (bus_to_baddr[(hwdev)->bus->number] + (addr))
+#define baddr_to_bus(hwdev, addr) ((addr) - bus_to_baddr[(hwdev)->bus->number])
+#else
+#define bus_to_baddr(hwdev, addr) (addr)
+#define baddr_to_bus(hwdev, addr) (addr)
+#endif
+
 /*
  * Slowdown I/O port space accesses for antique hardware.
  */
@@ -30,7 +40,13 @@
 #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
 
 #define __ioswab8(x) (x)
+#ifdef CONFIG_SGI_IP22
+/* IP22 seems braindead enough to swap 16bits values in hardware, but
+   not 32bits.  Go figure... Can't tell without documentation. */
+#define __ioswab16(x) (x)
+#else
 #define __ioswab16(x) swab16(x)
+#endif
 #define __ioswab32(x) swab32(x)
 
 #else
@@ -44,7 +60,7 @@
 /*
  * <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 :-) 
+ * 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
@@ -99,7 +115,7 @@
  *
  *     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. 
+ *     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
@@ -171,7 +187,7 @@
  *     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. 
+ *     address.
  */
 
 #define ioremap(offset, size)						\
@@ -186,11 +202,11 @@
  *     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. 
+ *     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 
+ *     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
@@ -259,7 +275,7 @@
 
 /*
  *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check 
+ *     @io_addr: mmio address to check
  *     @signature:  signature block
  *     @length: length of signature
  *
@@ -285,7 +301,7 @@
 
 /*
  *     isa_check_signature             -       find BIOS signatures
- *     @io_addr: mmio address to check 
+ *     @io_addr: mmio address to check
  *     @signature:  signature block
  *     @length: length of signature
  *
diff -urN linux-2.4.20-pre6/include/asm-mips/ioctls.h linux-2.4.20-pre7/include/asm-mips/ioctls.h
--- linux-2.4.20-pre6/include/asm-mips/ioctls.h	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/include/asm-mips/ioctls.h	Thu Sep 12 20:01:49 2002
@@ -12,7 +12,7 @@
 #include <asm/ioctl.h>
 
 #define TCGETA		0x5401
-#define TCSETA		0x5402
+#define TCSETA		0x5402	/* Clashes with SNDCTL_TMR_START sound ioctl */
 #define TCSETAW		0x5403
 #define TCSETAF		0x5404
 
@@ -66,7 +66,7 @@
 #define TIOCGETP        0x7408
 #define TIOCSETP        0x7409
 #define TIOCSETN        0x740a			/* TIOCSETP wo flush */
- 
+
 /* #define TIOCSETA	_IOW('t', 20, struct termios) set termios struct */
 /* #define TIOCSETAW	_IOW('t', 21, struct termios) drain output, set */
 /* #define TIOCSETAF	_IOW('t', 22, struct termios) drn out, fls in, set */
diff -urN linux-2.4.20-pre6/include/asm-mips/ipc.h linux-2.4.20-pre7/include/asm-mips/ipc.h
--- linux-2.4.20-pre6/include/asm-mips/ipc.h	Fri Jun 25 17:37:53 1999
+++ linux-2.4.20-pre7/include/asm-mips/ipc.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef __ASM_MIPS_IPC_H
 #define __ASM_MIPS_IPC_H
 
-/* 
+/*
  * These are used to wrap system calls on MIPS.
  *
  * See arch/mips/kernel/sysmips.c for ugly details..
diff -urN linux-2.4.20-pre6/include/asm-mips/ipcbuf.h linux-2.4.20-pre7/include/asm-mips/ipcbuf.h
--- linux-2.4.20-pre6/include/asm-mips/ipcbuf.h	Thu Feb 24 22:52:30 2000
+++ linux-2.4.20-pre7/include/asm-mips/ipcbuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_IPCBUF_H
 #define _ASM_IPCBUF_H
 
-/* 
+/*
  * The ipc64_perm structure for alpha architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
@@ -18,7 +18,7 @@
 	__kernel_gid_t	gid;
 	__kernel_uid_t	cuid;
 	__kernel_gid_t	cgid;
-	__kernel_mode_t	mode; 
+	__kernel_mode_t	mode;
 	unsigned short	seq;
 	unsigned short	__pad1;
 	unsigned long	__unused1;
diff -urN linux-2.4.20-pre6/include/asm-mips/irq.h linux-2.4.20-pre7/include/asm-mips/irq.h
--- linux-2.4.20-pre6/include/asm-mips/irq.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/irq.h	Thu Sep 12 20:01:49 2002
@@ -4,16 +4,16 @@
  * for more details.
  *
  * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
- * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 Kanoj Sarcar
  */
 #ifndef _ASM_IRQ_H
 #define _ASM_IRQ_H
 
 #include <linux/config.h>
 
-#define NR_IRQS 64		/* Largest number of ints of all machines.  */
-
-#define TIMER_IRQ 0
+#define NR_IRQS 128		/* Largest number of ints of all machines.  */
 
 #ifdef CONFIG_I8259
 static inline int irq_cannonicalize(int irq)
@@ -28,10 +28,10 @@
 extern int i8259_setup_irq(int irq, struct irqaction * new);
 extern void disable_irq(unsigned int);
 
-#ifndef CONFIG_NEW_IRQ
-#define disable_irq_nosync	disable_irq
-#else
+#ifdef CONFIG_NEW_IRQ
 extern void disable_irq_nosync(unsigned int);
+#else
+#define disable_irq_nosync	disable_irq
 #endif
 
 extern void enable_irq(unsigned int);
diff -urN linux-2.4.20-pre6/include/asm-mips/linux_logo.h linux-2.4.20-pre7/include/asm-mips/linux_logo.h
--- linux-2.4.20-pre6/include/asm-mips/linux_logo.h	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/include/asm-mips/linux_logo.h	Thu Sep 12 20:01:49 2002
@@ -17,7 +17,7 @@
  * Serial_console ascii image can be any size,
  * but should contain %s to display the version
  */
- 
+
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/config.h>
diff -urN linux-2.4.20-pre6/include/asm-mips/linux_logo_dec.h linux-2.4.20-pre7/include/asm-mips/linux_logo_dec.h
--- linux-2.4.20-pre6/include/asm-mips/linux_logo_dec.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/linux_logo_dec.h	Thu Sep 12 20:01:49 2002
@@ -8,7 +8,7 @@
  * Copyright (C) 2001 Jan-Benedict Glaw <jbglaw@lug-owl.de>
  *
  */
- 
+
 #include <linux/init.h>
 #include <linux/version.h>
 
diff -urN linux-2.4.20-pre6/include/asm-mips/mc146818rtc.h linux-2.4.20-pre7/include/asm-mips/mc146818rtc.h
--- linux-2.4.20-pre6/include/asm-mips/mc146818rtc.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mc146818rtc.h	Thu Sep 12 20:01:49 2002
@@ -6,35 +6,15 @@
  * Machine dependent access functions for RTC registers.
  *
  * Copyright (C) 1996, 1997, 1998, 2000 Ralf Baechle
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #ifndef _ASM_MC146818RTC_H
 #define _ASM_MC146818RTC_H
 
 #include <linux/config.h>
+
 #include <asm/io.h>
 
-#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
-#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) ({ \
-rtc_ops->rtc_read_data(addr); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-rtc_ops->rtc_write_data(val, addr); \
-})
-#define RTC_ALWAYS_BCD \
-rtc_ops->rtc_bcd_mode()
 
 /*
  * This structure defines how to access various features of
@@ -49,17 +29,46 @@
 
 extern struct rtc_ops *rtc_ops;
 
+/*
+ * Most supported machines access the RTC index register via an ISA
+ * port access but the way to access the date register differs ...
+ * The DECstation directly maps the RTC memory in the CPU's address
+ * space with the chipset generating necessary index write/data access
+ * cycles automagically.
+ */
+#define CMOS_READ(addr) ({ \
+rtc_ops->rtc_read_data(addr); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+rtc_ops->rtc_write_data(val, addr); \
+})
+#define RTC_ALWAYS_BCD \
+rtc_ops->rtc_bcd_mode()
+
+
 #ifdef CONFIG_DECSTATION
-#define RTC_IRQ 0
+
+#include <asm/dec/rtc-dec.h>
+
 #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
+
+#define RTC_PORT(x)	(0x14014800 + (x))
+#define RTC_IOMAPPED	0
+#define RTC_IRQ		IT8172_RTC_IRQ
+
+#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
+
+#define RTC_PORT(x)	(0x0c000000 + (x))
+#define RTC_IOMAPPED	0
+#define RTC_IRQ		0
+
 #else
-#define RTC_IRQ	8
-#endif
 
-#define RTC_DEC_YEAR	0x3f	/* Where we store the real year on DECs.  */
+#define RTC_PORT(x)	(0x70 + (x))
+#define RTC_IRQ		8
+
+#endif
 
 #endif /* _ASM_MC146818RTC_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/atlas.h linux-2.4.20-pre7/include/asm-mips/mips-boards/atlas.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/atlas.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/atlas.h	Thu Sep 12 20:01:49 2002
@@ -27,7 +27,7 @@
 
 #include <asm/addrspace.h>
 
-/* 
+/*
  * Atlas RTC-device indirect register access.
  */
 #define ATLAS_RTC_ADR_REG       (KSEG1ADDR(0x1f000800))
@@ -43,7 +43,7 @@
  * Atlas UART register base.
  */
 #define ATLAS_UART_REGS_BASE    (0x1f000900)
-#define ATLAS_BASE_BAUD ( 3686400 / 16 ) 
+#define ATLAS_BASE_BAUD ( 3686400 / 16 )
 
 /*
  * Atlas PSU standby register.
@@ -54,7 +54,7 @@
 /*
  * We make a universal assumption about the way the bootloader (YAMON)
  * have located the Philips SAA9730 chip.
- * This is not ideal, but is needed for setting up remote debugging as 
+ * This is not ideal, but is needed for setting up remote debugging as
  * soon as possible.
  */
 #define ATLAS_SAA9730_REG  (KSEG1ADDR(0x08800000))
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/atlasint.h linux-2.4.20-pre7/include/asm-mips/mips-boards/atlasint.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/atlasint.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/atlasint.h	Thu Sep 12 20:01:49 2002
@@ -29,8 +29,8 @@
 #define ATLASINT_UART      0
 #define ATLASINT_END      32
 
-/* 
- * Atlas registers are memory mapped on 64-bit aligned boundaries and 
+/*
+ * Atlas registers are memory mapped on 64-bit aligned boundaries and
  * only word access are allowed.
  */
 struct atlas_ictrl_regs {
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/bonito64.h linux-2.4.20-pre7/include/asm-mips/mips-boards/bonito64.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/bonito64.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/bonito64.h	Thu Sep 12 20:01:49 2002
@@ -11,7 +11,7 @@
  */
 
 /*
- * Bonito Register Map 
+ * Bonito Register Map
  * Copyright (c) 1999 Algorithmics Ltd
  *
  * Algorithmics gives permission for anyone to use and modify this file
@@ -20,7 +20,7 @@
  *
  * 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).
  */
@@ -75,7 +75,7 @@
 #define BONITO_PCICFG_BASE		0x1fe80000
 #define BONITO_PCICFG_SIZE		0x00080000
 #define BONITO_PCICFG_TOP		(BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
- 
+
 
 /* Bonito Register Bases */
 
@@ -184,7 +184,7 @@
 #define BONITO_PCIMAP_CFG		BONITO(BONITO_REGBASE + 0x18)
 
 /* 5. ICU & GPIO regs */
- 
+
 /* GPIO Regs - r/w */
 
 #define BONITO_GPIODATA_OFFSET          0x1c
@@ -231,7 +231,7 @@
 */
 
 /* 7. IDE DMA & Copier */
- 
+
 #define BONITO_CONFIGBASE		0x000
 #define BONITO_BONITOBASE		0x100
 #define BONITO_LDMABASE 		0x200
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/malta.h linux-2.4.20-pre7/include/asm-mips/mips-boards/malta.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/malta.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/malta.h	Thu Sep 12 20:01:49 2002
@@ -28,15 +28,15 @@
 #include <asm/addrspace.h>
 #include <asm/io.h>
 
-/* 
+/*
  * Malta I/O ports base address for the Galileo GT64120 and Algorithmics
- * Bonito system controllers. 
+ * 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.
  */
 #define MALTA_RTC_ADR_REG       0x70
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/msc01_pci.h linux-2.4.20-pre7/include/asm-mips/mips-boards/msc01_pci.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/msc01_pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/msc01_pci.h	Thu Sep 12 20:01:49 2002
@@ -94,7 +94,7 @@
 #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_DTO_BIT        0x00000100
 #define MSC01_PCI_INTCFG_MA_SHF         7
 #define MSC01_PCI_INTCFG_MA_MSK         0x00000080
 #define MSC01_PCI_INTCFG_MA_BIT         0x00000080
@@ -128,7 +128,7 @@
 #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_DTO_BIT       0x00000100
 #define MSC01_PCI_INTSTAT_MA_SHF        7
 #define MSC01_PCI_INTSTAT_MA_MSK        0x00000080
 #define MSC01_PCI_INTSTAT_MA_BIT        0x00000080
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/sead.h linux-2.4.20-pre7/include/asm-mips/mips-boards/sead.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/sead.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/sead.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,36 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * ########################################################################
+ *
+ * Defines of the SEAD board specific address-MAP, registers, etc.
+ *
+ */
+#ifndef _MIPS_SEAD_H
+#define _MIPS_SEAD_H
+
+#include <asm/addrspace.h>
+
+/*
+ * SEAD UART register base.
+ */
+#define SEAD_UART0_REGS_BASE    (0x1f000800)
+#define SEAD_BASE_BAUD ( 3686400 / 16 )
+
+#endif /* !(_MIPS_SEAD_H) */
diff -urN linux-2.4.20-pre6/include/asm-mips/mips-boards/seadint.h linux-2.4.20-pre7/include/asm-mips/mips-boards/seadint.h
--- linux-2.4.20-pre6/include/asm-mips/mips-boards/seadint.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/mips-boards/seadint.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,35 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * ########################################################################
+ *
+ * Defines for the SEAD interrupt controller.
+ *
+ */
+#ifndef _MIPS_SEADINT_H
+#define _MIPS_SEADINT_H
+
+/* Number of IRQ supported */
+#define SEADINT_UART0     0
+#define SEADINT_UART1     1
+#define SEADINT_END       2
+
+extern void seadint_init(void);
+
+#endif /* !(_MIPS_SEADINT_H) */
diff -urN linux-2.4.20-pre6/include/asm-mips/mips32_cache.h linux-2.4.20-pre7/include/asm-mips/mips32_cache.h
--- linux-2.4.20-pre6/include/asm-mips/mips32_cache.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mips32_cache.h	Thu Sep 12 20:01:49 2002
@@ -22,7 +22,7 @@
  * ########################################################################
  *
  * Inline assembly cache operations.
- * 
+ *
  * This file is the original r4cache.c file with modification that makes the
  * cache handling more generic.
  *
diff -urN linux-2.4.20-pre6/include/asm-mips/mipsregs.h linux-2.4.20-pre7/include/asm-mips/mipsregs.h
--- linux-2.4.20-pre6/include/asm-mips/mipsregs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mipsregs.h	Thu Sep 12 20:01:49 2002
@@ -77,7 +77,7 @@
 #define CP0_IWATCH $18
 #define CP0_DWATCH $19
 
-/* 
+/*
  * Coprocessor 0 Set 1 register names
  */
 #define CP0_S1_DERRADDR0  $26
@@ -374,8 +374,10 @@
 #define CONF_CM_CACHABLE_CUW		6
 #define CONF_CM_CACHABLE_ACCELERATED	7
 #define CONF_CM_CMASK			7
+#define CONF_CU				(1 <<  3)
 #define CONF_DB				(1 <<  4)
 #define CONF_IB				(1 <<  5)
+#define CONF_SE 			(1 << 12)
 #define CONF_SC				(1 << 17)
 #define CONF_AC                         (1 << 23)
 #define CONF_HALT                       (1 << 25)
@@ -527,8 +529,8 @@
         ".set\tmips0"                                           \
         : : "r" (value))
 
-/* 
- * This should be changed when we get a compiler that support the MIPS32 ISA. 
+/*
+ * This should be changed when we get a compiler that support the MIPS32 ISA.
  */
 #define read_mips32_cp0_config1()                               \
 ({ int __res;                                                   \
@@ -623,6 +625,8 @@
 
 #if defined(CONFIG_64BIT_PHYS_ADDR) && !defined(CONFIG_CPU_MIPS32)
 
+#include <asm/system.h>
+
 /*
  * These versions are only needed for systems with more than 38 bits of
  * physical address space.
diff -urN linux-2.4.20-pre6/include/asm-mips/mmu_context.h linux-2.4.20-pre7/include/asm-mips/mmu_context.h
--- linux-2.4.20-pre6/include/asm-mips/mmu_context.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/mmu_context.h	Thu Sep 12 20:01:49 2002
@@ -19,7 +19,7 @@
 /*
  * 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 
+ * 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.
@@ -85,10 +85,10 @@
 #ifndef CONFIG_SMP
 	mm->context = 0;
 #else
-	mm->context = (unsigned long)kmalloc(smp_num_cpus * 
+	mm->context = (unsigned long)kmalloc(smp_num_cpus *
 				sizeof(unsigned long), GFP_KERNEL);
 	/*
- 	 * Init the "context" values so that a tlbpid allocation 
+ 	 * Init the "context" values so that a tlbpid allocation
 	 * happens on the first switch.
  	 */
 	if (mm->context == 0)
diff -urN linux-2.4.20-pre6/include/asm-mips/msgbuf.h linux-2.4.20-pre7/include/asm-mips/msgbuf.h
--- linux-2.4.20-pre6/include/asm-mips/msgbuf.h	Thu Feb 24 22:52:30 2000
+++ linux-2.4.20-pre7/include/asm-mips/msgbuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_MSGBUF_H
 #define _ASM_MSGBUF_H
 
-/* 
+/*
  * The msqid64_ds structure for alpha architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
@@ -13,15 +13,18 @@
 struct msqid64_ds {
 	struct ipc64_perm msg_perm;
 	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
 	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
 	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
 	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;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
 };
 
 #endif /* _ASM_MSGBUF_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/ng1hw.h linux-2.4.20-pre7/include/asm-mips/ng1hw.h
--- linux-2.4.20-pre6/include/asm-mips/ng1hw.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/ng1hw.h	Thu Sep 12 20:01:49 2002
@@ -74,7 +74,7 @@
 #define DM0_XYOFFSET		NPORT_DMODE0_XYOFF
 #define DM0_CICLAMP		NPORT_DMODE0_CLAMP
 #define DM0_ENDPTFILTER		NPORT_DMODE0_ENDPF
-#define	DM0_YSTRIDE		NPORT_DMODE0_YSTR 
+#define	DM0_YSTRIDE		NPORT_DMODE0_YSTR
 
 #define DM1_PLANES_SHIFT	0
 /* The rest of the DM1 planes defines are in newport.h */
@@ -116,7 +116,7 @@
 
 #define DM1_SF_SHIFT		19
 #define DM1_SF_MASK   		NPORT_DMODE1_SFMASK
-#define DM1_SF			NPORT_DMODE1_SFMASK 
+#define DM1_SF			NPORT_DMODE1_SFMASK
 #define DM1_SF_ZERO		NPORT_DMODE1_SF0
 #define DM1_SF_ONE		NPORT_DMODE1_SF1
 #define DM1_SF_DC		NPORT_DMODE1_SFDC
@@ -125,8 +125,8 @@
 #define DM1_SF_MSA		NPORT_DMODE1_SFMSA
 
 #define DM1_DF_SHIFT		22	/* dfactor(2:0)	*/
-#define DM1_DF_MASK		NPORT_DMODE1_DFMASK 
-#define DM1_DF			NPORT_DMODE1_DFMASK 
+#define DM1_DF_MASK		NPORT_DMODE1_DFMASK
+#define DM1_DF			NPORT_DMODE1_DFMASK
 #define DM1_DF_ZERO		NPORT_DMODE1_DF0
 #define DM1_DF_ONE		NPORT_DMODE1_DF1
 #define DM1_DF_SC		NPORT_DMODE1_DFSC
@@ -174,23 +174,23 @@
 #define VRINT           	NPORT_STAT_VRINT
 #define VIDEOINT        	NPORT_STAT_VIDINT
 #define GFIFO_LEVEL_SHIFT       7
-#define GFIFO_LEVEL_MASK        NPORT_STAT_GLMSK 
+#define GFIFO_LEVEL_MASK        NPORT_STAT_GLMSK
 #define BFIFO_LEVEL_SHIFT       13
-#define BFIFO_LEVEL_MASK        NPORT_STAT_BLMSK 
+#define BFIFO_LEVEL_MASK        NPORT_STAT_BLMSK
 #define BFIFO_INT        	NPORT_STAT_BFIRQ
 #define GFIFO_INT        	NPORT_STAT_GFIRQ
 
-#define GIO32MODE		NPORT_CFG_G32MD 
+#define GIO32MODE		NPORT_CFG_G32MD
 #define BUSWIDTH		NPORT_CFG_BWIDTH
-#define EXTREGXCVR		NPORT_CFG_ERCVR 
+#define EXTREGXCVR		NPORT_CFG_ERCVR
 #define BFIFODEPTH_SHIFT	3
 #define BFIFODEPTH_MASK		NPORT_CFG_BDMSK
 #define BFIFOABOVEINT		NPORT_CFG_BFAINT
 #define GFIFODEPTH_SHIFT        8
-#define GFIFODEPTH_MASK		NPORT_CFG_GDMSK 
+#define GFIFODEPTH_MASK		NPORT_CFG_GDMSK
 #define GFIFOABOVEINT		NPORT_CFG_GFAINT
 #define TIMEOUT_SHIFT		14
-#define TIMEOUT_MASK		NPORT_CFG_TOMSK 
+#define TIMEOUT_MASK		NPORT_CFG_TOMSK
 #define VREFRESH_SHIFT		17
 #define VREFRESH_MASK		NPORT_CFG_VRMSK
 #define FB_TYPE			NPORT_CFG_FBTYP
diff -urN linux-2.4.20-pre6/include/asm-mips/nile4.h linux-2.4.20-pre7/include/asm-mips/nile4.h
--- linux-2.4.20-pre6/include/asm-mips/nile4.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/nile4.h	Thu Sep 12 20:01:49 2002
@@ -9,6 +9,9 @@
  *	NEC Vrc 5074 System Controller Data Sheet, June 1998
  */
 
+#ifndef _ASM_NILE4_H
+#define _ASM_NILE4_H
+
 #define NILE4_BASE		0xbfa00000
 #define NILE4_SIZE		0x00200000		/* 2 MB */
 
@@ -290,8 +293,8 @@
 
 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_enable_irq(unsigned int nile4_irq);
+extern void nile4_disable_irq(unsigned 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);
@@ -303,3 +306,5 @@
 extern u8 nile4_i8259_iack(void);
 extern void nile4_dump_irq_status(void);	/* Debug */
 
+#endif
+
diff -urN linux-2.4.20-pre6/include/asm-mips/page.h linux-2.4.20-pre7/include/asm-mips/page.h
--- linux-2.4.20-pre6/include/asm-mips/page.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/page.h	Thu Sep 12 20:01:49 2002
@@ -115,6 +115,8 @@
  * We handle pages at KSEG0 for kernels with 32 bit address space.
  */
 #define PAGE_OFFSET	0x80000000UL
+#define UNCAC_BASE	0xa0000000UL
+
 #define __pa(x)		((unsigned long) (x) - PAGE_OFFSET)
 #define __va(x)		((void *)((unsigned long) (x) + PAGE_OFFSET))
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
@@ -123,6 +125,9 @@
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
 				VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
+#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
+
 /*
  * Memory above this physical address will be considered highmem.
  */
diff -urN linux-2.4.20-pre6/include/asm-mips/pb1000.h linux-2.4.20-pre7/include/asm-mips/pb1000.h
--- linux-2.4.20-pre6/include/asm-mips/pb1000.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/pb1000.h	Thu Sep 12 20:01:49 2002
@@ -22,13 +22,14 @@
  *
  * ########################################################################
  *
- * 
+ *
  */
 #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 PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
 
 #define PB1000_PCR     0xBE000000
   #define PCR_SLOT_0_VPP0  (1<<0)
diff -urN linux-2.4.20-pre6/include/asm-mips/pb1100.h linux-2.4.20-pre7/include/asm-mips/pb1100.h
--- linux-2.4.20-pre6/include/asm-mips/pb1100.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/pb1100.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,85 @@
+/*
+ * Alchemy Semi PB1100 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_PB1100_H
+#define __ASM_PB1100_H
+
+#define PB1100_IDENT          0xAE000000
+#define PB1100_BOARD_STATUS   0xAE000004
+  #define PB1100_ROM_SEL         (1<<15)
+  #define PB1100_ROM_SIZ         (1<<14)
+  #define PB1100_SWAP_BOOT       (1<<13)
+  #define PB1100_FLASH_WP        (1<<12)
+  #define PB1100_ROM_H_STS       (1<<11)
+  #define PB1100_ROM_L_STS       (1<<10)
+  #define PB1100_FLASH_H_STS      (1<<9)
+  #define PB1100_FLASH_L_STS      (1<<8)
+  #define PB1100_SRAM_SIZ         (1<<7)
+  #define PB1100_TSC_BUSY         (1<<6)
+  #define PB1100_PCMCIA_VS_MASK   (3<<4)
+  #define PB1100_RS232_CD         (1<<3)
+  #define PB1100_RS232_CTS        (1<<2)
+  #define PB1100_RS232_DSR        (1<<1)
+  #define PB1100_RS232_RI         (1<<0)
+
+#define PB1100_IRDA_RS232     0xAE00000C
+  #define PB1100_IRDA_FULL       (0<<14) /* full power */
+  #define PB1100_IRDA_SHUTDOWN   (1<<14)
+  #define PB1100_IRDA_TT         (2<<14) /* 2/3 power */
+  #define PB1100_IRDA_OT         (3<<14) /* 1/3 power */
+  #define PB1100_IRDA_FIR        (1<<13)
+
+#define PB1100_MEM_PCMCIA     0xAE000010
+  #define PB1100_SD_WP1_RO       (1<<15) /* read only */
+  #define PB1100_SD_WP0_RO       (1<<14) /* read only */
+  #define PB1100_SD_PWR1         (1<<11) /* applies power to SD1 */
+  #define PB1100_SD_PWR0         (1<<10) /* applies power to SD0 */
+  #define PB1100_SEL_SD_CONN1     (1<<9)
+  #define PB1100_SEL_SD_CONN0     (1<<8)
+  #define PB1100_PC_DEASSERT_RST  (1<<7)
+  #define PB1100_PC_DRV_EN        (1<<4)
+
+#define PB1100_G_CONTROL      0xAE000014 /* graphics control */
+
+#define PB1100_RST_VDDI       0xAE00001C
+  #define PB1100_SOFT_RESET      (1<<15) /* clear to reset the board */
+  #define PB1100_VDDI_MASK        (0x1F)
+
+#define PB1100_LEDS           0xAE000018
+
+/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED.
+ * 7:0 is the LED Display's decimal points.
+ */
+#define PB1100_HEX_LED        0xAE000018
+
+/* PCMCIA PB1100 specific defines */
+#define PCMCIA_MAX_SOCK 0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
+
+#endif /* __ASM_PB1100_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/pb1500.h linux-2.4.20-pre7/include/asm-mips/pb1500.h
--- linux-2.4.20-pre6/include/asm-mips/pb1500.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/pb1500.h	Thu Sep 12 20:01:49 2002
@@ -22,7 +22,7 @@
  *
  * ########################################################################
  *
- * 
+ *
  */
 #ifndef __ASM_PB1500_H
 #define __ASM_PB1500_H
@@ -31,7 +31,7 @@
 #define PB1500_BOARD_STATUS   0xAE000004
 #define PB1500_PCI_PCMCIA     0xAE000010
   #define PC_DEASSERT_RST           0x80
-  #define PC_DRV_EN                 0x10 
+  #define PC_DRV_EN                 0x10
 #define PB1500_G_CONTROL      0xAE000014
 #define PB1500_RST_VDDI       0xAE00001C
 #define PB1500_LEDS           0xAE000018
@@ -41,6 +41,7 @@
 
 /* PCMCIA PB1500 specific defines */
 #define PCMCIA_MAX_SOCK 0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
 
 /* VPP/VCC */
 #define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0))
diff -urN linux-2.4.20-pre6/include/asm-mips/pci.h linux-2.4.20-pre7/include/asm-mips/pci.h
--- linux-2.4.20-pre6/include/asm-mips/pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/pci.h	Thu Sep 12 20:01:49 2002
@@ -7,8 +7,6 @@
 #define _ASM_PCI_H
 
 #include <linux/config.h>
-#include <linux/types.h>
-#include <asm/io.h>			/* for virt_to_bus()  */
 
 #ifdef __KERNEL__
 
@@ -40,7 +38,6 @@
  * MIPS has everything mapped statically.
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/scatterlist.h>
@@ -57,6 +54,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).
@@ -89,14 +93,14 @@
 static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
 					size_t size, int direction)
 {
+	unsigned long addr = (unsigned long) ptr;
+
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-#ifdef CONFIG_NONCOHERENT_IO
-	dma_cache_wback_inv((unsigned long)ptr, size);
-#endif
+	dma_cache_wback_inv(addr, size);
 
-	return virt_to_bus(ptr);
+	return bus_to_baddr(hwdev->bus->number, __pa(ptr));
 }
 
 /*
@@ -113,7 +117,12 @@
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	/* Nothing to do */
+	if (direction != PCI_DMA_TODEVICE) {
+		unsigned long addr;
+
+		addr = baddr_to_bus(hwdev, dma_addr) + PAGE_OFFSET;
+		dma_cache_wback_inv(addr, size);
+	}
 }
 
 /*
@@ -129,13 +138,10 @@
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	addr = (unsigned long) page_address(page);
-	addr += offset;
-#ifdef CONFIG_NONCOHERENT_IO
+	addr = (unsigned long) page_address(page) + offset;
 	dma_cache_wback_inv(addr, size);
-#endif
 
-	return virt_to_bus((void *)addr);
+	return bus_to_baddr(hwdev, page_to_phys(page) + offset);
 }
 
 static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
@@ -143,7 +149,13 @@
 {
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
-	/* Nothing to do */
+
+	if (direction != PCI_DMA_TODEVICE) {
+		unsigned long addr;
+
+		addr = baddr_to_bus(hwdev, dma_address) + PAGE_OFFSET;
+		dma_cache_wback_inv(addr, size);
+	}
 }
 
 /* pci_unmap_{page,single} is a nop so... */
@@ -173,18 +185,25 @@
 static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 			     int nents, int direction)
 {
-#ifdef CONFIG_NONCOHERENT_IO
 	int i;
-#endif
 
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-#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);
-#endif
+	for (i = 0; i < nents; i++, sg++) {
+		if (sg->address && sg->page)
+			out_of_line_bug();
+		else if (!sg->address && !sg->page)
+			out_of_line_bug();
+
+		if (sg->address) {
+			dma_cache_wback_inv((unsigned long)sg->address,
+			                    sg->length);
+			sg->dma_address = bus_to_baddr(hwdev, __pa(sg->address));
+		} else
+			sg->dma_address = page_to_bus(sg->page) +
+			                  sg->offset;
+	}
 
 	return nents;
 }
@@ -197,10 +216,24 @@
 static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 				int nents, int direction)
 {
+	int i;
+
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	/* Nothing to do */
+	if (direction == PCI_DMA_TODEVICE)
+		return;
+
+	for (i = 0; i < nents; i++, sg++) {
+		if (sg->address && sg->page)
+			out_of_line_bug();
+		else if (!sg->address && !sg->page)
+			out_of_line_bug();
+
+		if (!sg->address)
+			continue;
+		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+	}
 }
 
 /*
@@ -217,12 +250,13 @@
 				       dma_addr_t dma_handle,
 				       size_t size, int direction)
 {
+	unsigned long addr;
+
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-#ifdef CONFIG_NONCOHERENT_IO
-	dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size);
-#endif
+	addr = baddr_to_bus(hwdev, dma_handle) + PAGE_OFFSET;
+	dma_cache_wback_inv(addr, size);
 }
 
 /*
@@ -250,7 +284,8 @@
 #endif
 }
 
-/* Return whether the given PCI device DMA address mask can
+/*
+ * 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.
@@ -262,47 +297,54 @@
 	 * so we can't guarantee allocations that must be
 	 * within a tighter range than GFP_DMA..
 	 */
-	if (mask < 0x1fffffff)
+#ifdef CONFIG_ISA
+	if (mask < 0x00ffffff)
 		return 0;
+#endif
 
 	return 1;
 }
 
 /* This is always fine. */
-/* Well ...  this actually needs more thought ...  */
-#define pci_dac_dma_supported(pci_dev, mask)	(0)
+#define pci_dac_dma_supported(pci_dev, mask)	(1)
 
-#if 0
-static __inline__ dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+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);
+	dma64_addr_t addr = page_to_phys(page) + offset;
+
+	return (dma64_addr_t) bus_to_baddr(hwdev->bus->number, addr);
 }
 
-static __inline__ struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+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);
+	unsigned long poff = baddr_to_bus(hwdev, 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)
+static inline unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
 {
-	return (dma_addr & ~PAGE_MASK);
+	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)
+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. */
+	unsigned long addr;
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	addr = baddr_to_bus(hwdev->bus->number, dma_addr) + PAGE_OFFSET;
+	dma_cache_wback_inv(addr, len);
 }
-#endif
 
-/* Return the index of the PCI controller for device. */
+/*
+ * Return the index of the PCI controller for device.
+ */
 #define pci_controller_num(pdev)	(0)
 
 /*
@@ -312,7 +354,7 @@
  * returns, or alternatively stop on the first sg_dma_len(sg) which
  * is 0.
  */
-#define sg_dma_address(sg)	(virt_to_bus((sg)->address))
+#define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
 #endif /* __KERNEL__ */
diff -urN linux-2.4.20-pre6/include/asm-mips/pci_channel.h linux-2.4.20-pre7/include/asm-mips/pci_channel.h
--- linux-2.4.20-pre6/include/asm-mips/pci_channel.h	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/include/asm-mips/pci_channel.h	Thu Sep 12 20:01:49 2002
@@ -23,7 +23,7 @@
 	int last_devfn;
 };
 
-/* 
+/*
  * each board defines an array of pci_channels, that ends with all NULL entry
  */
 extern struct pci_channel mips_pci_channels[];
@@ -33,7 +33,7 @@
  */
 extern void pcibios_fixup_irqs(void);
 
-/* 
+/*
  * board supplied pci fixup routines
  */
 extern void pcibios_fixup_resources(struct pci_dev *dev);
diff -urN linux-2.4.20-pre6/include/asm-mips/pgtable-bits.h linux-2.4.20-pre7/include/asm-mips/pgtable-bits.h
--- linux-2.4.20-pre6/include/asm-mips/pgtable-bits.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/pgtable-bits.h	Thu Sep 12 20:01:49 2002
@@ -3,16 +3,17 @@
  * 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.
+ * Copyright (C) 1994 - 2002 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
-#ifndef _ASM_CACHINGMODES_H
-#define _ASM_CACHINGMODES_H
+#ifndef _ASM_PGTABLE_BITS_H
+#define _ASM_PGTABLE_BITS_H
 
 #include <linux/config.h>
 
-/* Note that we shift the lower 32bits of each EntryLo[01] entry
+/*
+ * 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
@@ -63,10 +64,10 @@
 /* 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)  
+#define _CACHE_UNCACHED             (2<<9)
+#define _CACHE_CACHABLE_COW         (5<<9)
+#define _CACHE_CACHABLE_NONCOHERENT (5<<9)
+#define _CACHE_UNCACHED_ACCELERATED (7<<9)
 
 #else
 
@@ -74,9 +75,9 @@
 #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_CE          (4<<9)  /* R4[04]00MC only         */
+#define _CACHE_CACHABLE_COW         (5<<9)  /* R4[04]00MC only         */
+#define _CACHE_CACHABLE_CUW         (6<<9)  /* R4[04]00MC only         */
 #define _CACHE_UNCACHED_ACCELERATED (7<<9)  /* R10000 only             */
 
 #endif
@@ -89,10 +90,12 @@
 
 #ifdef CONFIG_MIPS_UNCACHED
 #define PAGE_CACHABLE_DEFAULT	_CACHE_UNCACHED
-#elif CONFIG_CPU_SB1
-#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
-#else
+#elif defined(CONFIG_NONCOHERENT_IO)
 #define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_NONCOHERENT
+#else
+#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
 #endif
 
-#endif /* _ASM_CACHINGMODES_H */
+#define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 9)
+
+#endif /* _ASM_PGTABLE_BITS_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/pgtable.h linux-2.4.20-pre7/include/asm-mips/pgtable.h
--- linux-2.4.20-pre6/include/asm-mips/pgtable.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/pgtable.h	Thu Sep 12 20:01:49 2002
@@ -73,7 +73,7 @@
 /*
  * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
  *	starting at the top and working down. This is for populating the
- *	TLB before trap_init() puts the TLB miss handler in place. It 
+ *	TLB before trap_init() puts the TLB miss handler in place. It
  *	should be used only for entries matching the actual page tables,
  *	to prevent inconsistencies.
  */
@@ -240,7 +240,7 @@
 }
 
 /*
- * (pmds are folded into pgds so this doesnt get actually called,
+ * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
@@ -436,7 +436,7 @@
 	return (pmd_t *) dir;
 }
 
-/* Find an entry in the third-level page table.. */ 
+/* Find an entry in the third-level page table.. */
 static inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
 {
 	return (pte_t *) (pmd_page(*dir)) +
diff -urN linux-2.4.20-pre6/include/asm-mips/pmc/ev64120.h linux-2.4.20-pre7/include/asm-mips/pmc/ev64120.h
--- linux-2.4.20-pre6/include/asm-mips/pmc/ev64120.h	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/include/asm-mips/pmc/ev64120.h	Wed Dec 31 16:00:00 1969
@@ -1,59 +0,0 @@
-/*
- * 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 _ASM_PMC_CP7000_H
-#define _ASM_PMC_CP7000_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 /* _ASM_PMC_CP7000_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/pmc/ev64120int.h linux-2.4.20-pre7/include/asm-mips/pmc/ev64120int.h
--- linux-2.4.20-pre6/include/asm-mips/pmc/ev64120int.h	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/include/asm-mips/pmc/ev64120int.h	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-#ifndef _ASM_PMC_CP7000INT_H
-#define _ASM_PMC_CP7000INT_H
-
-#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 MIPS.
- */
-
-#define TIMER	4
-#define INTA	2
-#define INTD	5
-
-#endif /* _ASM_PMC_CP7000INT_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/posix_types.h linux-2.4.20-pre7/include/asm-mips/posix_types.h
--- linux-2.4.20-pre6/include/asm-mips/posix_types.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/posix_types.h	Thu Sep 12 20:01:49 2002
@@ -67,7 +67,7 @@
 
 #undef __FD_ISSET
 static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{ 
+{
 	unsigned long __tmp = __fd / __NFDBITS;
 	unsigned long __rem = __fd % __NFDBITS;
 	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
diff -urN linux-2.4.20-pre6/include/asm-mips/prctl.h linux-2.4.20-pre7/include/asm-mips/prctl.h
--- linux-2.4.20-pre6/include/asm-mips/prctl.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/prctl.h	Thu Sep 12 20:01:49 2002
@@ -12,14 +12,14 @@
 #define PRDA ((struct prda *) PRDA_ADDRESS)
 
 struct prda_sys {
-	pid_t t_pid; 
+	pid_t t_pid;
         u32   t_hint;
         u32   t_dlactseq;
         u32   t_fpflags;
         u32   t_prid;		/* processor type, $prid CP0 register */
         u32   t_dlendseq;
         u64   t_unused1[5];
-        pid_t t_rpid;   
+        pid_t t_rpid;
         s32   t_resched;
         u32   t_unused[8];
         u32   t_cpu;		/* current/last cpu */
diff -urN linux-2.4.20-pre6/include/asm-mips/processor.h linux-2.4.20-pre7/include/asm-mips/processor.h
--- linux-2.4.20-pre6/include/asm-mips/processor.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/processor.h	Thu Sep 12 20:01:49 2002
@@ -43,6 +43,7 @@
 extern void r3081_wait(void);
 extern void r39xx_wait(void);
 extern void r4k_wait(void);
+extern void au1k_wait(void);
 
 extern struct cpuinfo_mips cpu_data[];
 extern unsigned int vced_count, vcei_count;
@@ -55,12 +56,13 @@
 
 /*
  * Bus types (default is ISA, but people can check others with these..)
- * MCA_bus hardcoded to 0 for now.
- *
- * This needs to be extended since MIPS systems are being delivered with
- * numerous different types of bus systems.
  */
+#ifdef CONFIG_EISA
 extern int EISA_bus;
+#else
+#define EISA_bus (0)
+#endif
+
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
diff -urN linux-2.4.20-pre6/include/asm-mips/riscos-syscall.h linux-2.4.20-pre7/include/asm-mips/riscos-syscall.h
--- linux-2.4.20-pre6/include/asm-mips/riscos-syscall.h	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/include/asm-mips/riscos-syscall.h	Thu Sep 12 20:01:49 2002
@@ -220,7 +220,7 @@
 #define __NR_SVR4_reserved62		(__NR_SVR4 + 199)
 #define __NR_SVR4_reserved63		(__NR_SVR4 + 200)
 #define __NR_SVR4_aread			(__NR_SVR4 + 201)
-#define __NR_SVR4_awrite		(__NR_SVR4 + 202)	
+#define __NR_SVR4_awrite		(__NR_SVR4 + 202)
 #define __NR_SVR4_listio		(__NR_SVR4 + 203)
 #define __NR_SVR4_mips_acancel		(__NR_SVR4 + 204)
 #define __NR_SVR4_astatus		(__NR_SVR4 + 205)
diff -urN linux-2.4.20-pre6/include/asm-mips/rrm.h linux-2.4.20-pre7/include/asm-mips/rrm.h
--- linux-2.4.20-pre6/include/asm-mips/rrm.h	Sat Aug 16 09:51:09 1997
+++ linux-2.4.20-pre7/include/asm-mips/rrm.h	Thu Sep 12 20:01:49 2002
@@ -77,7 +77,7 @@
  * RRM_BINDPROCTORN:
  *
  * Return value when the X server calls it: 0
- */ 
+ */
 struct RRM_BindProcToRN {
 	int      rnid;
 };
diff -urN linux-2.4.20-pre6/include/asm-mips/scatterlist.h linux-2.4.20-pre7/include/asm-mips/scatterlist.h
--- linux-2.4.20-pre6/include/asm-mips/scatterlist.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/scatterlist.h	Thu Sep 12 20:01:49 2002
@@ -2,17 +2,19 @@
 #define __ASM_SCATTERLIST_H
 
 struct scatterlist {
-	char * address;		/* Location data is to be transferred to */
+	char * address;		/* Location data is to be transferred to,
+				   NULL for highmem page */
 	struct page * page;	/* Location for highmem page, if any */
+	unsigned int offset;
+	dma_addr_t dma_address;
 	unsigned int length;
-	__u32 dvma_address;
 };
 
 struct mmu_sglist {
 	char *addr;
 	char *__dont_touch;
 	unsigned int len;
-	__u32 dvma_addr;
+	dma_addr_t dvma_addr;
 };
 
 #define ISA_DMA_THRESHOLD (0x00ffffff)
diff -urN linux-2.4.20-pre6/include/asm-mips/semaphore-helper.h linux-2.4.20-pre7/include/asm-mips/semaphore-helper.h
--- linux-2.4.20-pre6/include/asm-mips/semaphore-helper.h	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/include/asm-mips/semaphore-helper.h	Thu Sep 12 20:01:49 2002
@@ -25,19 +25,18 @@
 
 #ifdef CONFIG_CPU_HAS_LLSC
 
-static inline int
-waking_non_zero(struct semaphore *sem)
+static inline int waking_non_zero(struct semaphore *sem)
 {
 	int ret, tmp;
 
 	__asm__ __volatile__(
-	"1:\tll\t%1, %2\n\t"
+	"1:\tll\t%1, %2\t\t\t# waking_non_zero\n\t"
 	"blez\t%1, 2f\n\t"
 	"subu\t%0, %1, 1\n\t"
 	"sc\t%0, %2\n\t"
-	"beqz\t%0, 1b\n\t"
+	"beqz\t%0, 1b\n"
 	"2:"
-	: "=r" (ret), "=r" (tmp), "=m" (sem->waking)
+	: "=r" (ret), "=r" (tmp), "+m" (sem->waking)
 	: "0"(0));
 
 	return ret;
@@ -74,22 +73,22 @@
  *	-EINTR	interrupted
  *
  * We must undo the sem->count down_interruptible decrement
- * simultaneously and atomicly with the sem->waking adjustment,
+ * simultaneously and atomically with the sem->waking adjustment,
  * otherwise we can race with wake_one_more.
  *
- * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
+ * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words.
  *
- * This is crazy.  Normally it stricly forbidden to use 64-bit operations
+ * This is crazy.  Normally it's strictly forbidden to use 64-bit operations
  * in the 32-bit MIPS kernel.  In this case it's however ok because if an
  * interrupt has destroyed the upper half of registers sc will fail.
- * Note also that this will not work for MIPS32 CPUS!
+ * Note also that this will not work for MIPS32 CPUs!
  *
  * Pseudocode:
  *
  * If(sem->waking > 0) {
  *	Decrement(sem->waking)
  *	Return(SUCCESS)
- * } else If(segnal_pending(tsk)) {
+ * } else If(signal_pending(tsk)) {
  *	Increment(sem->count)
  *	Return(-EINTR)
  * } else {
@@ -127,12 +126,11 @@
 }
 
 /*
- * waking_non_zero_trylock is unused.  we do everything in 
+ * waking_non_zero_trylock is unused.  we do everything in
  * down_trylock and let non-ll/sc hosts bounce around.
  */
 
-static inline int
-waking_non_zero_trylock(struct semaphore *sem)
+static inline int waking_non_zero_trylock(struct semaphore *sem)
 {
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
diff -urN linux-2.4.20-pre6/include/asm-mips/semaphore.h linux-2.4.20-pre7/include/asm-mips/semaphore.h
--- linux-2.4.20-pre6/include/asm-mips/semaphore.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/asm-mips/semaphore.h	Thu Sep 12 20:01:49 2002
@@ -130,7 +130,7 @@
  * down_trylock returns 0 on success, 1 if we failed to get the lock.
  *
  * We must manipulate count and waking simultaneously and atomically.
- * Here, we this by using ll/sc on the pair of 32-bit words.  This
+ * Here, we do this by using lld/scd on the pair of 32-bit words.  This
  * won't work on MIPS32 platforms, however, and must be rewritten.
  *
  * Pseudocode:
diff -urN linux-2.4.20-pre6/include/asm-mips/sembuf.h linux-2.4.20-pre7/include/asm-mips/sembuf.h
--- linux-2.4.20-pre6/include/asm-mips/sembuf.h	Thu Feb 24 22:52:30 2000
+++ linux-2.4.20-pre7/include/asm-mips/sembuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_SEMBUF_H
 #define _ASM_SEMBUF_H
 
-/* 
+/*
  * The semid64_ds structure for the MIPS architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
diff -urN linux-2.4.20-pre6/include/asm-mips/serial.h linux-2.4.20-pre7/include/asm-mips/serial.h
--- linux-2.4.20-pre6/include/asm-mips/serial.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/serial.h	Thu Sep 12 20:01:49 2002
@@ -84,11 +84,22 @@
 #define ATLAS_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_MIPS_SEAD
+#include <asm/mips-boards/sead.h>
+#include <asm/mips-boards/seadint.h>
+#define SEAD_SERIAL_PORT_DEFNS			\
+	/* UART CLK   PORT IRQ     FLAGS        */			\
+	{ 0, SEAD_BASE_BAUD, SEAD_UART0_REGS_BASE, SEADINT_UART0, STD_COM_FLAGS },     /* ttyS0 */
+#else
+#define SEAD_SERIAL_PORT_DEFNS
+#endif
+
 #ifdef CONFIG_MIPS_COBALT
+#include <asm/cobalt/cobalt.h>
 #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 */
+	{ 0, COBALT_BASE_BAUD, 0xc800000, COBALT_SERIAL_IRQ, STD_COM_FLAGS },   /* ttyS0 */
 #else
 #define COBALT_SERIAL_PORT_DEFNS
 #endif
@@ -165,7 +176,7 @@
     { 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 },     
+      flags: UART1_FLAGS, type: 1 },
 #else
 #define TXX927_SERIAL_PORT_DEFNS
 #endif
@@ -267,29 +278,53 @@
 #define MOMENCO_OCELOT_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_MOMENCO_OCELOT_G
+/* Ordinary NS16552 duart with a 20MHz crystal.  */
+#define OCELOT_G_BASE_BAUD ( 20000000 / 16 )
+
+#define OCELOT_G_SERIAL1_IRQ	4
+#if 0
+#define OCELOT_G_SERIAL1_BASE	0xe0001020
+#else
+#define OCELOT_G_SERIAL1_BASE	0xfd000020
+#endif
+
+#define _OCELOT_G_SERIAL_INIT(int, base)				\
+	{ baud_base: OCELOT_G_BASE_BAUD, irq: int, flags: STD_COM_FLAGS,\
+	  iomem_base: (u8 *) base, iomem_reg_shift: 2,			\
+	  io_type: SERIAL_IO_MEM }
+#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS				\
+	_OCELOT_G_SERIAL_INIT(OCELOT_G_SERIAL1_IRQ, OCELOT_G_SERIAL1_BASE)
+#else
+#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS
+#endif
+
 #ifdef CONFIG_DDB5477
-#define DDB5477_SERIAL_PORT_DEFNS                                       \
-        { baud_base: BASE_BAUD, irq: 12, flags: STD_COM_FLAGS,          \
-          iomem_base: (u8*)0xbfa04200, iomem_reg_shift: 3,              \
+#include <asm/ddb5xxx/ddb5477.h>
+#define DDB5477_SERIAL_PORT_DEFNS                                             \
+        { baud_base: BASE_BAUD, irq: VRC5477_IRQ_UART0, flags: STD_COM_FLAGS, \
+          iomem_base: (u8*)0xbfa04200, iomem_reg_shift: 3,                    \
           io_type: SERIAL_IO_MEM},\
-        { baud_base: BASE_BAUD, irq: 28, flags: STD_COM_FLAGS,          \
-          iomem_base: (u8*)0xbfa04240, iomem_reg_shift: 3,              \
+        { baud_base: BASE_BAUD, irq: VRC5477_IRQ_UART1, flags: STD_COM_FLAGS, \
+          iomem_base: (u8*)0xbfa04240, iomem_reg_shift: 3,                    \
           io_type: SERIAL_IO_MEM},
 #else
 #define DDB5477_SERIAL_PORT_DEFNS
 #endif
 
-#define SERIAL_PORT_DFNS		\
-	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		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS		\
-	MOMENCO_OCELOT_SERIAL_PORT_DEFNS\
-	AU1000_SERIAL_PORT_DEFNS	\
-        TXX927_SERIAL_PORT_DEFNS        \
+#define SERIAL_PORT_DFNS			\
+	IVR_SERIAL_PORT_DEFNS           	\
+	ITE_SERIAL_PORT_DEFNS           	\
+	ATLAS_SERIAL_PORT_DEFNS			\
+	SEAD_SERIAL_PORT_DEFNS			\
+	COBALT_SERIAL_PORT_DEFNS		\
+	EV96100_SERIAL_PORT_DEFNS		\
+	JAZZ_SERIAL_PORT_DEFNS			\
+	STD_SERIAL_PORT_DEFNS			\
+	EXTRA_SERIAL_PORT_DEFNS			\
+	HUB6_SERIAL_PORT_DFNS			\
+	MOMENCO_OCELOT_SERIAL_PORT_DEFNS	\
+	MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS	\
+	AU1000_SERIAL_PORT_DEFNS		\
+        TXX927_SERIAL_PORT_DEFNS        	\
 	DDB5477_SERIAL_PORT_DEFNS
diff -urN linux-2.4.20-pre6/include/asm-mips/sgi/sgigio.h linux-2.4.20-pre7/include/asm-mips/sgi/sgigio.h
--- linux-2.4.20-pre6/include/asm-mips/sgi/sgigio.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sgi/sgigio.h	Thu Sep 12 20:01:49 2002
@@ -19,21 +19,21 @@
  *   1     EXP0      0x1f400000 - 0x1f5fffff   2MB
  *   2     EXP1      0x1f600000 - 0x1f9fffff   4MB
  *
- * There are un-slotted devices, HPC, I/O and misc devices, which are grouped 
+ * 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 
+ * 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 
+ * 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 
+ * 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 
+ * slot2  - this is the "expansion"-slot 1 (EXP1), do not confuse with
  *          slot 1 (EXP0).
  */
 
@@ -57,7 +57,7 @@
 	unsigned char	slot_number;
 	unsigned long	base_addr;
 	unsigned int	map_size;
-	
+
 	char		*name;
 	char		slot_name[5];
 };
diff -urN linux-2.4.20-pre6/include/asm-mips/sgi/sgihpc.h linux-2.4.20-pre7/include/asm-mips/sgi/sgihpc.h
--- linux-2.4.20-pre6/include/asm-mips/sgi/sgihpc.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sgi/sgihpc.h	Thu Sep 12 20:01:49 2002
@@ -45,8 +45,8 @@
 	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 register has 
-				 * copletely different meaning for read 
+	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) */
@@ -235,7 +235,7 @@
 	hpcreg scsi1_ext[256];	/* SCSI channel 1 external regs */
 	char _unused4[0x07c00];	/* It'll only hurt a little... */
 
-	/* Ethernet external registers. Noone use them so we need some 
+	/* 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 */
diff -urN linux-2.4.20-pre6/include/asm-mips/sgi/sgint23.h linux-2.4.20-pre7/include/asm-mips/sgi/sgint23.h
--- linux-2.4.20-pre6/include/asm-mips/sgi/sgint23.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sgi/sgint23.h	Thu Sep 12 20:01:49 2002
@@ -16,17 +16,18 @@
 /* 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. HPC DMA and MC DMA interrups
- * are not supported this way. Driver is supposed to allocate HPC/MC 
+ * 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 ;-) 
+ * HAL2 driver). This will prevent many complications, trust me ;-)
  *	--ladis
  */
-#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' */
+#define SGINT_EISA	0	/* INDIGO 2 has 16 EISA irq levels */
+#define SGINT_CPU	16	/* MIPS CPU define 8 interrupt sources */
+#define SGINT_LOCAL0	24	/* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1	32	/* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2	40	/* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3	48	/* INDY has 8 local3 vectored irq levels */
+#define SGINT_END	56	/* End of 'spaces' */
 
 /*
  * Individual interrupt definitions for the INDY and Indigo2
@@ -42,7 +43,7 @@
 #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_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 */
@@ -87,7 +88,7 @@
 #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 */
@@ -107,7 +108,7 @@
 #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 */
@@ -199,7 +200,7 @@
 #endif
 #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 
+/* I am guesing there are only two unused registers here
  * but I could be wrong...			- andrewb
  */
 /*	u32 _unused[3]; */
diff -urN linux-2.4.20-pre6/include/asm-mips/sgialib.h linux-2.4.20-pre7/include/asm-mips/sgialib.h
--- linux-2.4.20-pre6/include/asm-mips/sgialib.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sgialib.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,12 @@
 /*
- * sgialib.h: SGI ARCS firmware interface library for the Linux kernel.
+ * This file is subject to 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 library for the Linux kernel.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_SGIALIB_H
 #define _ASM_SGIALIB_H
@@ -10,15 +15,19 @@
 
 extern struct linux_romvec *romvec;
 extern int prom_argc;
-extern char **prom_argv, **prom_envp;
+
+extern LONG *_prom_argv, *_prom_envp;
+
+/* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
+   These macros take care of sign extension.  */
+#define prom_argv(index) ((char *) (long) _prom_argv[(index)])
+#define prom_argc(index) ((char *) (long) _prom_argc[(index)])
 
 extern int prom_flags;
-#define PROM_FLAG_ARCS  1
+#define PROM_FLAG_ARCS			1
+#define PROM_FLAG_USE_AS_CONSOLE	2
 
-/*
- * Init the PROM library and it's internal data structures.  Called
- * at boot time from head.S before start_kernel is invoked.
- */
+/* Init the PROM library and it's internal data structures. */
 extern void prom_init(int argc, char **argv, char **envp, int *prom_vec);
 
 /* Simple char-by-char console I/O. */
@@ -28,18 +37,31 @@
 /* Generic printf() using ARCS console I/O. */
 extern void prom_printf(char *fmt, ...);
 
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS    32
+struct prom_pmemblock {
+	LONG	base;		/* Within KSEG0 or XKPHYS. */
+	ULONG size;		/* In bytes. */
+	ULONG type;		/* free or prom memory */
+};
+
+/* Get next memory descriptor after CURR, returns first descriptor
+ * in chain is CURR is NULL.
+ */
+extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
 #define PROM_NULL_MDESC   ((struct linux_mdesc *) 0)
 
 /* Called by prom_init to setup the physical memory pmemblock
  * array.
  */
 extern void prom_meminit(void);
+extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
 
 /* PROM device tree library routines. */
 #define PROM_NULL_COMPONENT ((pcomponent *) 0)
 
 /* Get sibling component of THIS. */
-extern pcomponent *prom_getsibling(pcomponent *this);
+extern pcomponent *ArcGetPeer(pcomponent *this);
 
 /* Get child component of THIS. */
 extern pcomponent *ArcGetChild(pcomponent *this);
@@ -64,7 +86,7 @@
 extern void prom_identify_arch(void);
 
 /* Environment variable routines. */
-extern PCHAR ArcGetEnvironmentVariable(CHAR *name);
+extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
 extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
 
 /* ARCS command line acquisition and parsing. */
@@ -79,9 +101,9 @@
 extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt);
 extern long prom_open(char *name, enum linux_omode md, unsigned long *fd);
 extern long prom_close(unsigned long fd);
-extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt);
+extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
 extern long prom_getrstatus(unsigned long fd);
-extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt);
+extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
 extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm);
 extern long prom_mount(char *name, enum linux_mountops op);
 extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf);
@@ -93,13 +115,13 @@
 extern long prom_exec(char *name, long argc, char **argv, char **envp);
 
 /* Misc. routines. */
-extern void prom_halt(void) __attribute__((noreturn));
-extern void prom_powerdown(void) __attribute__((noreturn));
-extern void prom_restart(void) __attribute__((noreturn));
-extern void prom_reboot(void) __attribute__((noreturn));
-extern void ArcEnterInteractiveMode(void) __attribute__((noreturn));
-extern long prom_cfgsave(void);
-extern struct linux_sysid *prom_getsysid(void);
-extern void prom_cacheflush(void);
+extern VOID prom_halt(VOID) __attribute__((noreturn));
+extern VOID prom_powerdown(VOID) __attribute__((noreturn));
+extern VOID prom_restart(VOID) __attribute__((noreturn));
+extern VOID ArcReboot(VOID) __attribute__((noreturn));
+extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
+extern long prom_cfgsave(VOID);
+extern struct linux_sysid *prom_getsysid(VOID);
+extern VOID ArcFlushAllCaches(VOID);
 
 #endif /* _ASM_SGIALIB_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/sgiarcs.h linux-2.4.20-pre7/include/asm-mips/sgiarcs.h
--- linux-2.4.20-pre6/include/asm-mips/sgiarcs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sgiarcs.h	Thu Sep 12 20:01:49 2002
@@ -13,6 +13,7 @@
 #define _ASM_SGIARCS_H
 
 #include <linux/config.h>
+#include <asm/types.h>
 #include <asm/arc/types.h>
 
 /* Various ARCS error codes. */
@@ -115,7 +116,7 @@
 	arc_prog,    /* A loaded program resides here */
 	arc_atmp,    /* temporary storage area */
 	arc_aperm,   /* permanent storage */
-	arc_fcontig, /* Contiguous and free */    
+	arc_fcontig, /* Contiguous and free */
 };
 
 union linux_memtypes {
@@ -164,11 +165,11 @@
 /* This prom has a bolixed design. */
 struct linux_bigint {
 #ifdef __MIPSEL__
-	unsigned long lo;
-	long hi;
+	u32 lo;
+	s32 hi;
 #else /* !(__MIPSEL__) */
-	long hi;
-	unsigned long lo;
+	s32 hi;
+	u32 lo;
 #endif
 };
 
diff -urN linux-2.4.20-pre6/include/asm-mips/shmbuf.h linux-2.4.20-pre7/include/asm-mips/shmbuf.h
--- linux-2.4.20-pre6/include/asm-mips/shmbuf.h	Mon Jul  2 13:56:40 2001
+++ linux-2.4.20-pre7/include/asm-mips/shmbuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_SHMBUF_H
 #define _ASM_SHMBUF_H
 
-/* 
+/*
  * The shmid64_ds structure for the MIPS architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
diff -urN linux-2.4.20-pre6/include/asm-mips/shmiq.h linux-2.4.20-pre7/include/asm-mips/shmiq.h
--- linux-2.4.20-pre6/include/asm-mips/shmiq.h	Fri Apr 13 20:26:07 2001
+++ linux-2.4.20-pre7/include/asm-mips/shmiq.h	Thu Sep 12 20:01:49 2002
@@ -5,7 +5,7 @@
  *
  * This also contains some streams and idev bits.
  *
- * They may contain errors, please, refer to the source code of the Linux  
+ * They may contain errors, please, refer to the source code of the Linux
  * kernel for a definitive answer on what we have implemented
  *
  * Miguel.
@@ -91,7 +91,7 @@
  * head   is the user index into the events, user can modify this one.
  * tail   is managed by the kernel.
  * flags  is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED
- *        if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called 
+ *        if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called
  *        to notify the kernel.
  * events where the kernel sticks the events.
  */
@@ -186,14 +186,14 @@
         unsigned        hwMaxRes;
         int             hwMinVal;
         int             hwMaxVal;
-	
+
         unsigned char   possibleModes;
 #define IDEV_ABSOLUTE           0x0
 #define IDEV_RELATIVE           0x1
 #define IDEV_EITHER             0x2
-	
+
         unsigned char   mode;	/* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */
-	
+
         unsigned short  resolution;
         int             minVal;
         int             maxVal;
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/64bit.h linux-2.4.20-pre7/include/asm-mips/sibyte/64bit.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/64bit.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/64bit.h	Thu Sep 12 20:01:49 2002
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2000, 2001 Broadcom Corporation
+ * Copyright (C) 2002 Ralf Baechle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,56 +11,58 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
+#ifndef __ASM_SIBYTE_64BIT_H
+#define __ASM_SIBYTE_64BIT_H
 
+#include <linux/config.h>
 #include <linux/types.h>
+
+#ifdef CONFIG_MIPS32
+
 #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;
+	u32 low, high;
 	unsigned long flags;
-
 	high = val >> 32;
 	low = val & 0xffffffff;
+	// save_flags(flags);
 	__save_and_cli(flags);
 	__asm__ __volatile__ (
-		".set push\t\t\t# out64n"
+		".set push\n"
 		".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"
+		"   dsll32 $2, %1, 0   \n"
+		"   dsll32 $1, %0, 0   \n"
+		"   dsrl32 $2, $2, 0   \n"
+		"   or     $1, $1, $2  \n"
+		"   sd $1, (%2)\n"
 		".set pop\n"
-		: "=&r" (tmp)
-		: "r" (high), "r" (low), "r" (addr));
+		::"r" (high), "r" (low), "r" (addr)
+		:"$1", "$2");
 	__restore_flags(flags);
 }
 
 static inline u64 in64(unsigned long addr)
 {
-	unsigned long flags;
 	u32 low, high;
-
+	unsigned long flags;
 	__save_and_cli(flags);
 	__asm__ __volatile__ (
-		".set push\t\t\t# in64\n"
+		".set push\n"
 		".set noreorder\n"
 		".set noat     \n"
 		".set mips4    \n"
@@ -67,11 +70,43 @@
 		"  dsra32 %0, %1, 0\n"
 		"  sll    %1, %1, 0\n"
 		".set pop\n"
-		: "=r" (high), "=r" (low)
-		: "r" (addr));
+		:"=r" (high), "=r" (low): "r" (addr));
 	__restore_flags(flags);
-
 	return (((u64)high) << 32) | low;
 }
 
-#endif /* _SB1_64BIT_H */
+#endif /* CONFIG_MIPS32 */
+
+#ifdef CONFIG_MIPS64
+
+/*
+ * 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 /* CONFIG_MIPS64 */
+
+/*
+ * Avoid interrupt mucking, just adjust the address for 4-byte access.
+ * Assume the addresses are 8-byte aligned.
+ */
+
+#ifdef __MIPSEB__
+#define __CSR_32_ADJUST 4
+#else
+#define __CSR_32_ADJUST 0
+#endif
+
+#define csr_out32(v,a) (*(u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v))
+#define csr_in32(a)    (*(u32 *)((unsigned long)(a) + __CSR_32_ADJUST))
+
+#endif /* __ASM_SIBYTE_64BIT_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/board.h linux-2.4.20-pre7/include/asm-mips/sibyte/board.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/board.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/board.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,28 @@
+/*
+ * 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 _SIBYTE_BOARD_H
+#define _SIBYTE_BOARD_H
+
+#if defined(CONFIG_SIBYTE_PTSWARM) || defined(CONFIG_SIBYTE_SWARM)
+#include <asm/sibyte/swarm.h>
+#endif
+
+#endif
+
+
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250.h	Thu Sep 12 20:01:49 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -19,11 +19,21 @@
 #ifndef _ASM_SIBYTE_SB1250_H
 #define _ASM_SIBYTE_SB1250_H
 
+#ifndef __ASSEMBLY__
+
+#include <asm/addrspace.h>
+
+/* For revision/pass information */
+#include <asm/sibyte/sb1250_scd.h>
+extern unsigned int sb1250_pass;
+
 extern void sb1250_time_init(void);
+extern unsigned long sb1250_gettimeoffset(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
 
-#define IO_SPACE_BASE 0xa0000000UL
+#define IO_SPACE_BASE KSEG1
 
 #endif
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_defs.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_defs.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_defs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_defs.h	Thu Sep 12 20:01:49 2002
@@ -1,21 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
-    *  Global constants and macros		File: sb1250_defs.h	
-    *  
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -25,38 +27,38 @@
     *
     *  You 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, 
+    *  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). 
+    *
+    *  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 
+    *  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 
+    *                  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 
+    *  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
@@ -74,7 +76,7 @@
 #define _SB1250_DEFS_H
 
 /*
- * Cast to 64-bit number.  Presumably the syntax is different in 
+ * 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.
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_dma.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_dma.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_dma.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_dma.h	Thu Sep 12 20:01:49 2002
@@ -1,24 +1,24 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -28,7 +28,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -43,9 +43,9 @@
     *  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_RX_CH_0
  * Registers: DMA_CONFIG0_MAC_x_TX_CH_0
  * Registers: DMA_CONFIG0_SER_x_RX
  * Registers: DMA_CONFIG0_SER_x_TX
@@ -83,7 +83,7 @@
 
 /*
  * Ethernet and Serial DMA Configuration Register 2 (Table 7-5)
- * Registers: DMA_CONFIG1_MAC_x_RX_CH_0 
+ * 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
@@ -131,11 +131,11 @@
 /*
  * DMA Descriptor Count Registers (Table 7-8)
  */
- 
+
 /* No bitfields */
 
 
-/* 
+/*
  * Current Descriptor Address Register (Table 7-11)
  */
 
@@ -202,13 +202,16 @@
 #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)
 
+/* Note: BADTCPCS is actually in DSCR_A */
+#define M_DMA_ETHRX_BADTCPCS	_SB_MAKEMASK1(0)	/* PASS2 */
+
 #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)
@@ -241,7 +244,7 @@
 
 #define M_DMA_ETHTX_SOP	    	    _SB_MAKEMASK1(63)
 
-/* 
+/*
  * Ethernet Transmit Options (Table 7-17)
  */
 
@@ -294,7 +297,7 @@
     *  Data Mover Registers
     ********************************************************************* */
 
-/* 
+/*
  * Data Mover Descriptor Base Address Register (Table 7-22)
  * Register: DM_DSCR_BASE_0
  * Register: DM_DSCR_BASE_1
@@ -302,10 +305,10 @@
  * Register: DM_DSCR_BASE_3
  */
 
-#define M_DM_DSCR_BASE_MBZ          _SB_MAKEMASK(3,0)
+#define M_DM_DSCR_BASE_MBZ          _SB_MAKEMASK(4,0)
 
 /*  Note: Just mask the base address and then OR it in. */
-#define S_DM_DSCR_BASE_ADDR         _SB_MAKE64(3)
+#define S_DM_DSCR_BASE_ADDR         _SB_MAKE64(4)
 #define M_DM_DSCR_BASE_ADDR         _SB_MAKEMASK(36,S_DM_DSCR_BASE_ADDR)
 
 #define S_DM_DSCR_BASE_RINGSZ       _SB_MAKE64(40)
@@ -331,7 +334,7 @@
 #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)
  */
 
@@ -364,7 +367,10 @@
 #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 M_DM_DSCRA_THROTTLE         _SB_MAKEMASK1(43) */ /* REMOVED PASS2 */
+
+#define M_DM_DSCRA_RD_BKOFF	    _SB_MAKEMASK1(52)		/* PASS2 */
+#define M_DM_DSCRA_WR_BKOFF	    _SB_MAKEMASK1(53)		/* PASS2 */
 
 #define S_DM_DSCRA_DIR_DEST         _SB_MAKE64(44)
 #define M_DM_DSCRA_DIR_DEST         _SB_MAKEMASK(2,S_DM_DSCRA_DIR_DEST)
@@ -398,7 +404,7 @@
 #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)
+#define M_DM_DSCRA_RESERVED2        _SB_MAKEMASK(10,54)
 
 /*
  * Data Mover Descriptor Doubleword "B"  (Table 7-25)
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_genbus.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_genbus.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_genbus.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_genbus.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
+    *
     *  Generic Bus Constants                     File: sb1250_genbus.h
-    *  
-    *  This module contains constants and macros useful for 
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -48,11 +48,13 @@
 #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_1L       2		/* PASS2 */
 #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_BURST_EN		_SB_MAKEMASK1(5)	/* PASS2 */
 #define M_IO_PARITY_ODD		_SB_MAKEMASK1(6)
 #define M_IO_NONMUX		_SB_MAKEMASK1(7)
 
@@ -92,11 +94,18 @@
 #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 M_IO_EARLY_CS	        _SB_MAKEMASK1(3)	/* PASS2 */
+
 #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_BURST_WIDTH           _SB_MAKE64(6)			/* PASS2 */
+#define M_IO_BURST_WIDTH           _SB_MAKEMASK(2,S_IO_BURST_WIDTH)	/* PASS2 */
+#define V_IO_BURST_WIDTH(x)        _SB_MAKEVALUE(x,S_IO_BURST_WIDTH)	/* PASS2 */
+#define G_IO_BURST_WIDTH(x)        _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH)	/* PASS2 */
+
 #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)
@@ -117,6 +126,8 @@
 #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 M_IO_RDY_SYNC	        _SB_MAKEMASK1(3)	/* PASS2 */
+
 #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)
@@ -155,6 +166,7 @@
 #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)
+#define M_IO_COH_ERR	        _SB_MAKEMASK1(14)	/* PASS2 */
 
 /*
  * PCMCIA configuration register (Table 12-6)
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_int.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_int.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_int.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_int.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -43,7 +43,7 @@
 
 /*
  * Interrupt sources (Table 4-8, UM 0.2)
- * 
+ *
  * First, the interrupt numbers.
  */
 
@@ -77,8 +77,8 @@
 #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_CYCLE_CP0_INT	    30		/* PASS2 */
+#define K_INT_CYCLE_CP1_INT	    31		/* PASS2 */
 #define K_INT_GPIO_0                32
 #define K_INT_GPIO_1                33
 #define K_INT_GPIO_2                34
@@ -108,9 +108,9 @@
 #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
+#define K_INT_MAC_0_CH1		    61		/* PASS2 */
+#define K_INT_MAC_1_CH1		    62		/* PASS2 */
+#define K_INT_MAC_2_CH1		    63		/* PASS2 */
 
 /*
  * Mask values for each interrupt
@@ -146,8 +146,8 @@
 #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_CYCLE_CP0_INT	    _SB_MAKEMASK1(K_INT_CYCLE_CP0_INT)	/* PASS2 */
+#define M_INT_CYCLE_CP1_INT	    _SB_MAKEMASK1(K_INT_CYCLE_CP1_INT)	/* PASS2 */
 #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)
@@ -177,9 +177,9 @@
 #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)
+#define M_INT_MAC_0_CH1		    _SB_MAKEMASK1(K_INT_MAC_0_CH1)	/* PASS2 */
+#define M_INT_MAC_1_CH1		    _SB_MAKEMASK1(K_INT_MAC_1_CH1)	/* PASS2 */
+#define M_INT_MAC_2_CH1		    _SB_MAKEMASK1(K_INT_MAC_2_CH1)	/* PASS2 */
 
 /*
  * Interrupt mappings
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_l2c.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_l2c.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_l2c.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_l2c.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -76,6 +76,14 @@
 #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_QUADRANT         15
+#define M_L2C_MGMT_QUADRANT         _SB_MAKEMASK(2,S_L2C_MGMT_QUADRANT)
+#define V_L2C_MGMT_QUADRANT(x)      _SB_MAKEVALUE(x,S_L2C_MGMT_QUADRANT)
+#define G_L2C_MGMT_QUADRANT(x)      _SB_GETVALUE(x,S_L2C_MGMT_QUADRANT,M_L2C_MGMT_QUADRANT)
+
+#define S_L2C_MGMT_HALF		    16
+#define M_L2C_MGMT_HALF	            _SB_MAKEMASK(1,S_L2C_MGMT_HALF)
+
 #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)
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_ldt.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_ldt.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_ldt.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_ldt.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  This module contains constants and macros to describe
+    *  the LDT interface on the SB1250.
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -70,6 +70,7 @@
 #define R_LDT_TYPE1_SRIRXNUM	0x0058
 #define R_LDT_TYPE1_ERRSTATUS   0x0068
 #define R_LDT_TYPE1_SRICTRL	0x006C
+#define R_LDT_TYPE1_ADDSTATUS	0x0070		/* PASS2 */
 #define R_LDT_TYPE1_TXBUFCNT	0x00C8
 #define R_LDT_TYPE1_EXPCRC	0x00DC
 #define R_LDT_TYPE1_RXCRC	0x00F0
@@ -152,13 +153,14 @@
 
 /*
  * LDT Status Register (Table 8-14).  Note that these constants
- * assume you've read the command and status register 
+ * 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_VGAEN		_SB_MAKEMASK1_32(3)	/* PASS2 */
 #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)
@@ -177,8 +179,8 @@
 #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 
+ * Bridge Control Register (Table 8-16).  Note that these
+ * constants assume you've read the register as a 32-bit
  * read (offset 0x3C)
  */
 
@@ -279,7 +281,10 @@
 #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 M_LDT_SRICMD_DISSTARVATIONCNT	_SB_MAKEMASK1_32(19) */ /* PASS1 */
+#define M_LDT_SRICMD_DISMULTTXVLD	_SB_MAKEMASK1_32(19)	/* PASS2 */
+#define M_LDT_SRICMD_EXPENDIAN		_SB_MAKEMASK1_32(26)	/* PASS2 */
+
 
 #define S_LDT_SRICMD_RXMARGIN		20
 #define M_LDT_SRICMD_RXMARGIN		_SB_MAKEMASK_32(5,S_LDT_SRICMD_RXMARGIN)
@@ -397,6 +402,14 @@
 #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)
 
+/*
+ * Additional Status Register (PASS2)
+ */
+
+#define S_LDT_ADDSTATUS_TGTDONE		0
+#define M_LDT_ADDSTATUS_TGTDONE		_SB_MAKEMASK_32(8,S_LDT_ADDSTATUS_TGTDONE)
+#define V_LDT_ADDSTATUS_TGTDONE(x)	_SB_MAKEVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE)
+#define G_LDT_ADDSTATUS_TGTDONE(x)	_SB_GETVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE,M_LDT_ADDSTATUS_TGTDONE)
 
 #endif
 
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_mac.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_mac.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_mac.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_mac.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -49,8 +49,6 @@
  */
 
 
-/* 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)
@@ -130,7 +128,7 @@
 #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 M_MAC_RX_CH_SEL_MSB	    _SB_MAKEMASK1(44)		/* PASS2 */
 
 #define S_MAC_BYPASS_IFG            _SB_MAKE64(46)
 #define M_MAC_BYPASS_IFG            _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
@@ -202,12 +200,14 @@
  */
 
 #define S_MAC_TX_WR_THRSH           _SB_MAKE64(0)
-#define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH)
+/* #define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH) */ /* PASS1 */
+#define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(7,S_MAC_TX_WR_THRSH)	    /* PASS2 */
 #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 M_MAC_TX_RD_THRSH           _SB_MAKEMASK(6,S_MAC_TX_RD_THRSH) */ /* PASS1 */
+#define M_MAC_TX_RD_THRSH           _SB_MAKEMASK(7,S_MAC_TX_RD_THRSH)	    /* PASS2 */
 #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)
 
@@ -231,6 +231,11 @@
 #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)
 
+#define S_MAC_ENC_FC_THRSH           _SB_MAKE64(56)			/* PASS2 */
+#define M_MAC_ENC_FC_THRSH           _SB_MAKEMASK(6,S_MAC_ENC_FC_THRSH)	/* PASS2 */
+#define V_MAC_ENC_FC_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_ENC_FC_THRSH) /* PASS2 */
+#define G_MAC_ENC_FC_THRSH(x)        _SB_GETVALUE(x,S_MAC_ENC_FC_THRSH,M_MAC_ENC_FC_THRSH) /* PASS2 */
+
 /*
  * MAC Frame Configuration Registers (Table 9-15)
  * Register: MAC_FRAME_CFG_0
@@ -280,20 +285,20 @@
 
 /*
  * These constants are used to configure the fields within the Frame
- * Configuration Register.  
+ * 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_RX_10             _SB_MAKE64(0)	/* See table 176, not used */
+#define K_MAC_IFG_RX_100            _SB_MAKE64(0)
+#define K_MAC_IFG_RX_1000           _SB_MAKE64(0)
 
 #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_IFG_THRSH_10          _SB_MAKE64(4)
+#define K_MAC_IFG_THRSH_100         _SB_MAKE64(4)
+#define K_MAC_IFG_THRSH_1000        _SB_MAKE64(0)
 
 #define K_MAC_SLOT_SIZE_10          _SB_MAKE64(0)
 #define K_MAC_SLOT_SIZE_100         _SB_MAKE64(0)
@@ -317,9 +322,11 @@
 
 #define K_MAC_MIN_FRAMESZ_DEFAULT   _SB_MAKE64(64)
 #define K_MAC_MAX_FRAMESZ_DEFAULT   _SB_MAKE64(1518)
+#define K_MAC_MAX_FRAMESZ_JUMBO     _SB_MAKE64(9216)
 
 #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)
+#define V_MAC_MAX_FRAMESZ_JUMBO     V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_JUMBO)
 
 /*
  * MAC VLAN Tag Registers (Table 9-16)
@@ -341,7 +348,7 @@
  * 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.
@@ -378,6 +385,7 @@
 #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 M_MAC_SPLIT_EN		    _SB_MAKEMASK1(47) 	/* interrupt mask only */ /* PASS2 */
 
 #define S_MAC_COUNTER_ADDR          _SB_MAKE64(47)
 #define M_MAC_COUNTER_ADDR          _SB_MAKEMASK(5,S_MAC_COUNTER_ADDR)
@@ -498,6 +506,7 @@
 #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 M_MAC_ALLMCAST_EN	_SB_MAKEMASK1(7)	/* PASS2 */
 
 #define S_MAC_IPHDR_OFFSET      _SB_MAKE64(8)
 #define M_MAC_IPHDR_OFFSET      _SB_MAKEMASK(8,S_MAC_IPHDR_OFFSET)
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_mc.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_mc.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_mc.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_mc.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
-    *  Memory Controller constants              File: sb1250_mc.h       
-    *  
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -166,7 +166,7 @@
 
 #define K_MC_REF_RATE_100MHz         0x62
 #define K_MC_REF_RATE_133MHz         0x81
-#define K_MC_REF_RATE_200MHz         0xC4 
+#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)
@@ -224,7 +224,7 @@
                                      V_MC_ADDR_DRIVE_DEFAULT | \
                                      V_MC_DATA_DRIVE_DEFAULT | \
                                      V_MC_CLOCK_DRIVE_DEFAULT | \
-                                     V_MC_REF_RATE_DEFAULT 
+                                     V_MC_REF_RATE_DEFAULT
 
 
 
@@ -298,69 +298,80 @@
  * SDRAM Timing Register  (Table 6-15)
  */
 
-#define M_MC_w2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(62)
+#define M_MC_w2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(60)
 #define M_MC_r2wIDLE_TWOCYCLES	  _SB_MAKEMASK1(61)
-#define M_MC_r2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(60)
+#define M_MC_r2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(62)
 
 #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 G_MC_tFIFO(x)             _SB_GETVALUE(x,S_MC_tFIFO,M_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 G_MC_tRFC(x)              _SB_GETVALUE(x,S_MC_tRFC,M_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 G_MC_tCwCr(x)             _SB_GETVALUE(x,S_MC_tCwCr,M_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 G_MC_tRCr(x)              _SB_GETVALUE(x,S_MC_tRCr,M_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 G_MC_tRCw(x)              _SB_GETVALUE(x,S_MC_tRCw,M_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 G_MC_tRRD(x)              _SB_GETVALUE(x,S_MC_tRRD,M_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 G_MC_tRP(x)               _SB_GETVALUE(x,S_MC_tRP,M_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 G_MC_tCwD(x)              _SB_GETVALUE(x,S_MC_tCwD,M_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 M_MC_tCrDh		  M_tCrDh
 
 #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 G_MC_tCrD(x)              _SB_GETVALUE(x,S_MC_tCrD,M_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 G_MC_tRCD(x)              _SB_GETVALUE(x,S_MC_tRCD,M_MC_tRCD)
 #define K_MC_tRCD_DEFAULT         3
 #define V_MC_tRCD_DEFAULT         V_MC_tRCD(K_MC_tRCD_DEFAULT)
 
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_pci.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_pci.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_pci.h	Wed Dec 31 16:00:00 1969
@@ -1,250 +0,0 @@
-/*  *********************************************************************
-    *  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 -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_prof.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_prof.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_prof.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_prof.h	Thu Sep 12 20:01:49 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_regs.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_regs.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_regs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_regs.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  01/02/2002
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -40,20 +40,20 @@
 
 /*  *********************************************************************
     *  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.  
-    *  
+    *  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
     ********************************************************************* */
 
@@ -97,7 +97,7 @@
 #define R_MC_TEST_ECC               0x0000000420
 #define R_MC_MCLK_CFG               0x0000000500
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * L2 Cache Control Registers
     ********************************************************************* */
 
@@ -107,7 +107,12 @@
 #define A_L2_MAKEDISABLE(x)         (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8))
 #define A_L2_MGMT_TAG_BASE          0x00D0000000
 
-/*  ********************************************************************* 
+#define A_L2_CACHE_DISABLE	   0x0010042000	/* PASS2 */
+#define A_L2_MAKECACHEDISABLE(x)   (A_L2_CACHE_DISABLE | (((x)&0x0F) << 8))	/* PASS2 */
+#define A_L2_MISC_CONFIG	   0x0010043000	/* PASS2 */
+
+
+/*  *********************************************************************
     * PCI Interface Registers
     ********************************************************************* */
 
@@ -115,7 +120,7 @@
 #define A_PCI_TYPE01_HEADER         0x00DE000800
 
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * Ethernet DMA and MACs
     ********************************************************************* */
 
@@ -162,7 +167,7 @@
             (R_MAC_DMA_CHANNEL_BASE(txrx,chan) +    \
             (reg))
 
-/* 
+/*
  * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE
  */
 
@@ -220,6 +225,7 @@
 #define R_MAC_INT_MASK                  0x00000410
 #define R_MAC_TXD_CTL                   0x00000420
 #define R_MAC_MDIO                      0x00000428
+#define R_MAC_STATUS1		        0x00000430	/* PASS2 */
 #define R_MAC_DEBUG_STATUS              0x00000448
 
 #define MAC_HASH_COUNT			8
@@ -227,7 +233,7 @@
 #define MAC_CHMAP_COUNT			4
 
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * DUART Registers
     ********************************************************************* */
 
@@ -250,6 +256,11 @@
 #define R_DUART_RX_HOLD             0x160
 #define R_DUART_TX_HOLD             0x170
 
+#define R_DUART_FULL_CTL	    0x140	/* PASS2 */
+#define R_DUART_OPCR_X		    0x180	/* PASS2 */
+#define R_DUART_AUXCTL_X	    0x190	/* PASS2 */
+
+
 /*
  * The IMR and ISR can't be addressed with A_DUART_CHANREG,
  * so use this macro instead.
@@ -310,7 +321,16 @@
 #define A_DUART_INPORT_CHNG_A       0x00100603D0
 #define A_DUART_INPORT_CHNG_B       0x00100603E0
 
-/*  ********************************************************************* 
+#define A_DUART_FULL_CTL_A	    0x0010060140	/* PASS2 */
+#define A_DUART_FULL_CTL_B	    0x0010060240	/* PASS2 */
+
+#define A_DUART_OPCR_A	  	    0x0010060180	/* PASS2 */
+#define A_DUART_OPCR_B	  	    0x0010060280	/* PASS2 */
+
+#define A_DUART_INPORT_CHNG_DEBUG   0x00100603F0	/* PASS2 */
+
+
+/*  *********************************************************************
     * Synchronous Serial Registers
     ********************************************************************* */
 
@@ -344,7 +364,7 @@
             (reg))
 
 
-/* 
+/*
  * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE
  */
 
@@ -404,7 +424,7 @@
 #define R_SER_RMON_RX_ERRORS        0x000001F0
 #define R_SER_RMON_RX_BADADDR       0x000001F8
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * Generic Bus Registers
     ********************************************************************* */
 
@@ -456,7 +476,7 @@
 #define R_IO_PCMCIA_CFG             0x0A60
 #define R_IO_PCMCIA_STATUS          0x0A70
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * GPIO Registers
     ********************************************************************* */
 
@@ -480,7 +500,7 @@
 #define R_GPIO_PIN_CLR              0x30
 #define R_GPIO_PIN_SET              0x38
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * SMBus Registers
     ********************************************************************* */
 
@@ -516,7 +536,7 @@
 #define R_SMB_CONTROL               0x0000000060
 #define R_SMB_PEC                   0x0000000070
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * Timer Registers
     ********************************************************************* */
 
@@ -575,16 +595,21 @@
 #define A_SCD_TIMER_CNT_3           0x0010020188
 #define A_SCD_TIMER_CFG_3           0x0010020198
 
-/*  ********************************************************************* 
+#define A_SCD_SCRATCH		   0x0010020C10		/* PASS2 */
+
+#define A_SCD_ZBBUS_CYCLE_COUNT	   0x0010030000		/* PASS2 */
+#define A_SCD_ZBBUS_CYCLE_CP0	   0x0010020C00		/* PASS2 */
+#define A_SCD_ZBBUS_CYCLE_CP1	   0x0010020C08		/* PASS2 */
+
+
+/*  *********************************************************************
     * 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
     ********************************************************************* */
 
@@ -602,9 +627,10 @@
 #define A_ADDR_TRAP_CFG_1           0x0010020448
 #define A_ADDR_TRAP_CFG_2           0x0010020450
 #define A_ADDR_TRAP_CFG_3           0x0010020458
+#define A_ADDR_TRAP_REG_DEBUG	    0x0010020460	/* PASS2 */
 
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * System Interrupt Mapper Registers
     ********************************************************************* */
 
@@ -632,7 +658,7 @@
 #define R_IMR_INTERRUPT_MAP_BASE        0x0200
 #define R_IMR_INTERRUPT_MAP_COUNT       64
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * System Performance Counter Registers
     ********************************************************************* */
 
@@ -642,11 +668,12 @@
 #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_SCD_BUS_ERR_STATUS_DEBUG  0x00100208D0	/* PASS2 */
 #define A_BUS_ERR_DATA_0            0x00100208A0
 #define A_BUS_ERR_DATA_1            0x00100208A8
 #define A_BUS_ERR_DATA_2            0x00100208B0
@@ -654,13 +681,13 @@
 #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
     ********************************************************************* */
 
@@ -683,7 +710,7 @@
 #define A_SCD_TRACE_SEQUENCE_6      0x0010020A90
 #define A_SCD_TRACE_SEQUENCE_7      0x0010020A98
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * System Generic DMA Registers
     ********************************************************************* */
 
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_scd.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_scd.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_scd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_scd.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -53,7 +53,8 @@
 
 #define K_SYS_REVISION_PASS1	    1
 #define K_SYS_REVISION_PASS2	    3
-#define K_SYS_REVISION_PASS3	    4 /* XXX Unknown */
+#define K_SYS_REVISION_PASS2_2	    16
+#define K_SYS_REVISION_PASS3	    32
 
 #define S_SYS_PART                  _SB_MAKE64(16)
 #define M_SYS_PART                  _SB_MAKEMASK(16,S_SYS_PART)
@@ -61,7 +62,7 @@
 #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 K_SYS_PART_SB1125           0x1125
 
 #define S_SYS_WID                   _SB_MAKE64(32)
 #define M_SYS_WID                   _SB_MAKEMASK(32,S_SYS_WID)
@@ -153,6 +154,9 @@
 #define M_SYS_MISR_MODE             _SB_MAKEMASK1(61)
 #define M_SYS_MISR_RESET            _SB_MAKEMASK1(62)
 
+#define M_SYS_SW_FLAG		    _SB_MAKEMASK1(63)	/* PASS2 */
+
+
 /*
  * Mailbox Registers (Table 4-3)
  * Registers: SCD_MBOX_CPU_x
@@ -346,6 +350,7 @@
 #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 M_SCD_TRACE_CFG_FORCECNT        _SB_MAKEMASK1(8)	/* PASS2 */
 
 #define S_SCD_TRACE_CFG_CUR_ADDR        10
 #define M_SCD_TRACE_CFG_CUR_ADDR        _SB_MAKEMASK(8,S_SCD_TRACE_CFG_CUR_ADDR)
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_smbus.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_smbus.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_smbus.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_smbus.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
+    *
     *  SMBUS Constants                          File: sb1250_smbus.h
-    *  
-    *  This module contains constants and macros useful for 
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  01/02/2002
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -131,4 +131,44 @@
 #define M_SPEC_PEC                  _SB_MAKEMASK(8,S_SPEC_PEC)
 #define V_SPEC_MB(x)                _SB_MAKEVALUE(x,S_SPEC_PEC)
 
+
+/*  *********************************************************************
+    *  PASS2 Extensions to SMBus
+    ********************************************************************* */
+
+/* BEGIN PASS2 */
+
+#define S_SMB_CMDH                  8
+#define M_SMB_CMDH                  _SB_MAKEMASK(8,S_SMBH_CMD)
+#define V_SMB_CMDH(x)               _SB_MAKEVALUE(x,S_SMBH_CMD)
+
+#define M_SMB_EXTEND		    _SB_MAKEMASK1(14)
+
+#define M_SMB_DIR		    _SB_MAKEMASK1(13)
+
+#define S_SMB_DFMT                  8
+#define M_SMB_DFMT                  _SB_MAKEMASK(3,S_SMB_DFMT)
+#define V_SMB_DFMT(x)               _SB_MAKEVALUE(x,S_SMB_DFMT)
+#define G_SMB_DFMT(x)               _SB_GETVALUE(x,S_SMB_DFMT,M_SMB_DFMT)
+
+#define K_SMB_DFMT_1BYTE            0
+#define K_SMB_DFMT_2BYTE            1
+#define K_SMB_DFMT_3BYTE            2
+#define K_SMB_DFMT_4BYTE            3
+#define K_SMB_DFMT_NODATA           4
+#define K_SMB_DFMT_CMD4BYTE         5
+#define K_SMB_DFMT_CMD5BYTE         6
+#define K_SMB_DFMT_RESERVED         7
+
+#define V_SMB_DFMT_1BYTE	    V_SMB_DFMT(K_SMB_DFMT_1BYTE)
+#define V_SMB_DFMT_2BYTE	    V_SMB_DFMT(K_SMB_DFMT_2BYTE)
+#define V_SMB_DFMT_3BYTE	    V_SMB_DFMT(K_SMB_DFMT_3BYTE)
+#define V_SMB_DFMT_4BYTE	    V_SMB_DFMT(K_SMB_DFMT_4BYTE)
+#define V_SMB_DFMT_NODATA	    V_SMB_DFMT(K_SMB_DFMT_NODATA)
+#define V_SMB_DFMT_CMD4BYTE	    V_SMB_DFMT(K_SMB_DFMT_CMD4BYTE)
+#define V_SMB_DFMT_CMD5BYTE	    V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE)
+#define V_SMB_DFMT_RESERVED	    V_SMB_DFMT(K_SMB_DFMT_RESERVED)
+
+/* END PASS2 */
+
 #endif
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_syncser.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_syncser.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_syncser.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_syncser.h	Thu Sep 12 20:01:49 2002
@@ -6,18 +6,18 @@
     *  This module contains constants and macros useful for
     *  manipulating the SB1250's Synchronous Serial
     *
-    *  SB1250 specification level:  0.2
+    *  SB1250 specification level:  User's manual 1/02/02
     *
-    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_uart.h linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_uart.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/sb1250_uart.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/sb1250_uart.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
+    *
     *  UART Constants				File: sb1250_uart.h
-    *  
-    *  This module contains constants and macros useful for 
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -37,7 +37,7 @@
 
 #include "sb1250_defs.h"
 
-/* ********************************************************************** 
+/* **********************************************************************
    * DUART Registers
    ********************************************************************** */
 
@@ -144,7 +144,7 @@
 #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) 
+#define M_DUART_CMD_RESERVED             _SB_MAKEMASK1(7)
 
 /*
  * DUART Status Register (Table 10-6)
@@ -164,7 +164,7 @@
 
 /*
  * DUART Baud Rate Register (Table 10-7)
- * Register: DUART_CLK_SEL_A 
+ * Register: DUART_CLK_SEL_A
  * Register: DUART_CLK_SEL_B
  */
 
@@ -229,6 +229,9 @@
 #define M_DUART_IP3_CHNG_ENA        _SB_MAKEMASK1(3)
 #define M_DUART_ACR_RESERVED        _SB_MAKEMASK(4,4)
 
+#define M_DUART_CTS_CHNG_ENA        _SB_MAKEMASK1(0)
+#define M_DUART_CIN_CHNG_ENA        _SB_MAKEMASK1(2)
+
 /*
  * DUART Interrupt Status Register (Table 10-16)
  * Register: DUART_ISR
@@ -327,9 +330,20 @@
     (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
 
 /*
- * XXX To be added: Synchronous Serial definitions
+ * Full Interrupt Control Register (PASS2)
  */
 
+#define S_DUART_SIG_FULL           _SB_MAKE64(0)
+#define M_DUART_SIG_FULL           _SB_MAKEMASK(4,S_DUART_SIG_FULL)
+#define V_DUART_SIG_FULL(x)        _SB_MAKEVALUE(x,S_DUART_SIG_FULL)
+#define G_DUART_SIG_FULL(x)        _SB_GETVALUE(x,S_DUART_SIG_FULL,M_DUART_SIG_FULL)
+
+#define S_DUART_INT_TIME           _SB_MAKE64(4)
+#define M_DUART_INT_TIME           _SB_MAKEMASK(4,S_DUART_INT_TIME)
+#define V_DUART_INT_TIME(x)        _SB_MAKEVALUE(x,S_DUART_INT_TIME)
+#define G_DUART_INT_TIME(x)        _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME)
+
+
 /* ********************************************************************** */
 
 
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/swarm.h linux-2.4.20-pre7/include/asm-mips/sibyte/swarm.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/swarm.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/swarm.h	Thu Sep 12 20:01:49 2002
@@ -10,20 +10,57 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
 
-#ifndef _ASM_SIBYTE_SWARM_H
-#define _ASM_SIBYTE_SWARM_H
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_int.h>
 
 #define KERNEL_RESERVED_MEM 0x100000
-#define LED_BASE_ADDR 0x100a0020
 
+#define LEDS_CS         3
+
+#ifdef CONFIG_SIBYTE_SWARM
+
+/* Generic bus chip selects */
+#define IDE_CS          4
+#define PCMCIA_CS       6
+
+/* GPIOs */
+#define K_GPIO_GB_IDE   4
+#define K_INT_GB_IDE    (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#define K_GPIO_PC_READY 9
+#define K_INT_PC_READY  (K_INT_GPIO_0 + K_GPIO_PC_READY)
+
+#endif
+
+#ifdef __ASSEMBLY__
+#define setleds(t0,t1,c0,c1,c2,c3) \
+	li	t0, (LED_BASE_ADDR|0xa0000000); \
+	li	t1, c0; \
+	sb	t1, 0x18(t0); \
+	li	t1, c1; \
+	sb	t1, 0x10(t0); \
+	li	t1, c2; \
+	sb	t1, 0x08(t0); \
+	li	t1, c3; \
+	sb	t1, 0x00(t0)
+#else
 void swarm_setup(void);
+void setleds(char *str);
 
-void setleds(char *str); 
+#define AT_spin \
+	__asm__ __volatile__ (		\
+		".set noat\n"		\
+		"li $at, 0\n"		\
+		"1: beqz $at, 1b\n"	\
+		".set at\n"		\
+		)
+#endif
 
-#endif /* _ASM_SIBYTE_SWARM_H */
+#endif /* __ASM_SIBYTE_SWARM_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/sibyte/swarm_ide.h linux-2.4.20-pre7/include/asm-mips/sibyte/swarm_ide.h
--- linux-2.4.20-pre6/include/asm-mips/sibyte/swarm_ide.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/sibyte/swarm_ide.h	Thu Sep 12 20:01:49 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
diff -urN linux-2.4.20-pre6/include/asm-mips/siginfo.h linux-2.4.20-pre7/include/asm-mips/siginfo.h
--- linux-2.4.20-pre6/include/asm-mips/siginfo.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/siginfo.h	Thu Sep 12 20:01:49 2002
@@ -203,8 +203,8 @@
 
 /*
  * sigevent definitions
- * 
- * It seems likely that SIGEV_THREAD will have to be handled from 
+ *
+ * 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.
diff -urN linux-2.4.20-pre6/include/asm-mips/signal.h linux-2.4.20-pre7/include/asm-mips/signal.h
--- linux-2.4.20-pre6/include/asm-mips/signal.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/signal.h	Thu Sep 12 20:01:49 2002
@@ -88,7 +88,7 @@
 
 #define SA_RESTORER	0x04000000
 
-/* 
+/*
  * sigaltstack controls
  */
 #define SS_ONSTACK     1
diff -urN linux-2.4.20-pre6/include/asm-mips/smp.h linux-2.4.20-pre7/include/asm-mips/smp.h
--- linux-2.4.20-pre6/include/asm-mips/smp.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/smp.h	Thu Sep 12 20:01:49 2002
@@ -10,11 +10,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
@@ -63,8 +63,8 @@
 
 #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)))
+#define CPUMASK_CLRB(p, bit)	(p) &= ~(1UL << (bit))
+#define CPUMASK_TSTB(p, bit)	((p) & (1UL << (bit)))
 
 #elif (NR_CPUS <= 128)
 
@@ -81,11 +81,11 @@
 
 #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))
+					(1UL << CPUMASK_SHFT(bit))
 #define CPUMASK_CLRB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] &= \
-					~(1ULL << CPUMASK_SHFT(bit))
+					~(1UL << CPUMASK_SHFT(bit))
 #define CPUMASK_TSTB(p, bit)	((p)._bits[CPUMASK_INDEX(bit)] & \
-					(1ULL << CPUMASK_SHFT(bit)))
+					(1UL << CPUMASK_SHFT(bit)))
 
 #else
 #error cpumask macros only defined for 128p kernels
diff -urN linux-2.4.20-pre6/include/asm-mips/softirq.h linux-2.4.20-pre7/include/asm-mips/softirq.h
--- linux-2.4.20-pre6/include/asm-mips/softirq.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/softirq.h	Thu Sep 12 20:01:49 2002
@@ -18,7 +18,7 @@
 	local_bh_count(cpu)++;
 	barrier();
 }
- 
+
 static inline void __cpu_bh_enable(int cpu)
 {
 	barrier();
diff -urN linux-2.4.20-pre6/include/asm-mips/spinlock.h linux-2.4.20-pre7/include/asm-mips/spinlock.h
--- linux-2.4.20-pre6/include/asm-mips/spinlock.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/spinlock.h	Thu Sep 12 20:01:49 2002
@@ -55,7 +55,7 @@
 	".set\tnoreorder\t\t\t# spin_unlock\n\t"
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (lock->lock)
 	: "m" (lock->lock)
 	: "memory");
@@ -92,7 +92,7 @@
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock), "=&r" (tmp)
 	: "m" (rw->lock)
 	: "memory");
@@ -112,7 +112,7 @@
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock), "=&r" (tmp)
 	: "m" (rw->lock)
 	: "memory");
@@ -130,7 +130,7 @@
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock), "=&r" (tmp)
 	: "m" (rw->lock)
 	: "memory");
@@ -142,7 +142,7 @@
 	".set\tnoreorder\t\t\t# write_unlock\n\t"
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock)
 	: "m" (rw->lock)
 	: "memory");
diff -urN linux-2.4.20-pre6/include/asm-mips/stackframe.h linux-2.4.20-pre7/include/asm-mips/stackframe.h
--- linux-2.4.20-pre6/include/asm-mips/stackframe.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/stackframe.h	Thu Sep 12 20:01:49 2002
@@ -55,14 +55,14 @@
                 srl     k0, k0, 23;                      \
 		sll     k0, k0, 2;                       \
                 addu    k1, k0;                          \
-                lw      k1, %lo(kernelsp)(k1);        
+                lw      k1, %lo(kernelsp)(k1);
 
 #else
 #  define GET_SAVED_SP                                   \
 		lui	k1, %hi(kernelsp);               \
-		lw	k1, %lo(kernelsp)(k1);           
+		lw	k1, %lo(kernelsp)(k1);
 #endif
- 
+
 #define SAVE_SOME                                        \
 		.set	push;                            \
 		.set	reorder;                         \
diff -urN linux-2.4.20-pre6/include/asm-mips/string.h linux-2.4.20-pre7/include/asm-mips/string.h
--- linux-2.4.20-pre6/include/asm-mips/string.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/string.h	Thu Sep 12 20:01:49 2002
@@ -109,7 +109,7 @@
 	"2:\n\t"
 #if defined(CONFIG_CPU_R3000)
 	"nop\n\t"
-#endif	
+#endif
 	"move\t%3,$1\n"
 	"3:\tsubu\t%3,$1\n\t"
 	".set\tat\n\t"
diff -urN linux-2.4.20-pre6/include/asm-mips/system.h linux-2.4.20-pre7/include/asm-mips/system.h
--- linux-2.4.20-pre6/include/asm-mips/system.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/system.h	Thu Sep 12 20:01:49 2002
@@ -8,7 +8,7 @@
  * Copyright (C) 1994 - 1999 by Ralf Baechle
  *
  * Changed set_except_vector declaration to allow return of previous
- * vector address value - necessary for "borrowing" vectors. 
+ * vector address value - necessary for "borrowing" vectors.
  *
  * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.
@@ -18,9 +18,12 @@
 
 #include <linux/config.h>
 #include <asm/sgidefs.h>
-#include <asm/ptrace.h>
+
 #include <linux/kernel.h>
 
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+
 __asm__ (
 	".macro\t__sti\n\t"
 	".set\tpush\n\t"
@@ -101,7 +104,7 @@
 	"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"	
+	".set\tpop\n\t"
 	".endm");
 
 #define __save_and_cli(x)						\
@@ -145,7 +148,7 @@
 extern unsigned long __global_save_flags(void);
 extern void __global_restore_flags(unsigned long);
 #  define sti() __global_sti()
-#  define cli() __global_cli() 
+#  define cli() __global_cli()
 #  define save_flags(x) do { x = __global_save_flags(); } while (0)
 #  define restore_flags(x) __global_restore_flags(x)
 #  define save_and_cli(x) do { save_flags(x); cli(); } while(0)
@@ -166,32 +169,58 @@
 #define local_irq_disable()	__cli()
 #define local_irq_enable()	__sti()
 
-/*
- * These are probably defined overly paranoid ...
- */
+#ifdef CONFIG_CPU_HAS_SYNC
+#define __sync()				\
+	__asm__ __volatile__(			\
+		".set	push\n\t"		\
+		".set	noreorder\n\t"		\
+		".set	mips2\n\t"		\
+		"sync\n\t"			\
+		".set	pop"			\
+		: /* no output */		\
+		: /* no input */		\
+		: "memory")
+#else
+#define __sync()	do { } while(0)
+#endif
+
+#define __fast_iob()				\
+	__asm__ __volatile__(			\
+		".set	push\n\t"		\
+		".set	noreorder\n\t"		\
+		"lw	$0,%0\n\t"		\
+		"nop\n\t"			\
+		".set	pop"			\
+		: /* no output */		\
+		: "m" (*(int *)KSEG1)		\
+		: "memory")
+
+#define fast_wmb()	__sync()
+#define fast_rmb()	__sync()
+#define fast_mb()	__sync()
+#define fast_iob()				\
+	do {					\
+		__sync();			\
+		__fast_iob();			\
+	} while (0)
+
 #ifdef CONFIG_CPU_HAS_WB
 
 #include <asm/wbflush.h>
-#define rmb()	do { } while(0)
-#define wmb()	wbflush()
-#define mb()	wbflush()
-
-#else /* CONFIG_CPU_HAS_WB  */
-
-#define mb()						\
-__asm__ __volatile__(					\
-	"# prevent instructions being moved around\n\t"	\
-	".set\tnoreorder\n\t"				\
-	"# 8 nops to fool the R4400 pipeline\n\t"	\
-	"nop;nop;nop;nop;nop;nop;nop;nop\n\t"		\
-	".set\treorder"					\
-	: /* no output */				\
-	: /* no input */				\
-	: "memory")
-#define rmb() mb()
-#define wmb() mb()
 
-#endif /* CONFIG_CPU_HAS_WB  */
+#define wmb()		fast_wmb()
+#define rmb()		fast_rmb()
+#define mb()		wbflush();
+#define iob()		wbflush();
+
+#else /* !CONFIG_CPU_HAS_WB */
+
+#define wmb()		fast_wmb()
+#define rmb()		fast_rmb()
+#define mb()		fast_mb()
+#define iob()		fast_iob()
+
+#endif /* !CONFIG_CPU_HAS_WB */
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
@@ -218,6 +247,14 @@
 #endif /* !__ASSEMBLY__ */
 
 #define prepare_to_switch()	do { } while(0)
+
+struct task_struct;
+
+extern asmlinkage void lazy_fpu_switch(void *);
+extern asmlinkage void init_fpu(void);
+extern asmlinkage void save_fp(struct task_struct *);
+extern asmlinkage void restore_fp(struct task_struct *);
+
 #define switch_to(prev,next,last) \
 do { \
 	(last) = resume(prev, next); \
@@ -275,14 +312,14 @@
 
 extern void *set_except_vector(int n, void *addr);
 
-extern void __die(const char *, struct pt_regs *, const char *where,
-	unsigned long line) __attribute__((noreturn));
-extern void __die_if_kernel(const char *, struct pt_regs *, const char *where,
-	unsigned long line);
+extern void __die(const char *, struct pt_regs *, const char *file,
+	const char *func, unsigned long line) __attribute__((noreturn));
+extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
+	const char *func, unsigned long line);
 
 #define die(msg, regs)							\
-	__die(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
+	__die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
 #define die_if_kernel(msg, regs)					\
-	__die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__)
+	__die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
 
 #endif /* _ASM_SYSTEM_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/time.h linux-2.4.20-pre7/include/asm-mips/time.h
--- linux-2.4.20-pre6/include/asm-mips/time.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/time.h	Thu Sep 12 20:01:49 2002
@@ -23,7 +23,7 @@
 #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.
@@ -39,7 +39,7 @@
 extern void to_tm(unsigned long tim, struct rtc_time * tm);
 
 /*
- * do_gettimeoffset(). By default, this func pointer points to 
+ * 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.
  */
diff -urN linux-2.4.20-pre6/include/asm-mips/timex.h linux-2.4.20-pre7/include/asm-mips/timex.h
--- linux-2.4.20-pre6/include/asm-mips/timex.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/asm-mips/timex.h	Thu Sep 12 20:01:49 2002
@@ -21,7 +21,7 @@
  * Standard way to access the cycle counter.
  * Currently only used on SMP for scheduling.
  *
- * Only the low 32 bits are available as a continuously counting entity. 
+ * Only the low 32 bits are available as a continuously counting entity.
  * But this only means we'll force a reschedule every 8 seconds or so,
  * which isn't an evil thing.
  *
diff -urN linux-2.4.20-pre6/include/asm-mips/types.h linux-2.4.20-pre7/include/asm-mips/types.h
--- linux-2.4.20-pre6/include/asm-mips/types.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/types.h	Thu Sep 12 20:01:49 2002
@@ -33,12 +33,12 @@
 typedef unsigned long __u64;
 
 #else
- 
+
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 typedef __signed__ long long __s64;
 typedef unsigned long long __u64;
 #endif
- 
+
 #endif
 
 /*
@@ -71,10 +71,10 @@
 
 #define BITS_PER_LONG _MIPS_SZLONG
 
-#ifdef CONFIG_64BIT_PHYS_ADDR
-typedef u32 dma_addr_t;
-#else
+#if defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)
 typedef u64 dma_addr_t;
+#else
+typedef u32 dma_addr_t;
 #endif
 typedef u64 dma64_addr_t;
 
diff -urN linux-2.4.20-pre6/include/asm-mips/umap.h linux-2.4.20-pre7/include/asm-mips/umap.h
--- linux-2.4.20-pre6/include/asm-mips/umap.h	Fri Jun 25 17:37:53 1999
+++ linux-2.4.20-pre7/include/asm-mips/umap.h	Thu Sep 12 20:01:49 2002
@@ -4,5 +4,5 @@
 void remove_mapping (struct task_struct *task, unsigned long start,
 unsigned long end);
 
-#endif 
+#endif
 
diff -urN linux-2.4.20-pre6/include/asm-mips/unaligned.h linux-2.4.20-pre7/include/asm-mips/unaligned.h
--- linux-2.4.20-pre6/include/asm-mips/unaligned.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/unaligned.h	Thu Sep 12 20:01:49 2002
@@ -93,8 +93,8 @@
  * get_unaligned - get value from possibly mis-aligned location
  * @ptr: pointer to value
  *
- * This macro should be used for accessing values larger in size than 
- * single bytes at locations that are expected to be improperly aligned, 
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
  * e.g. retrieving a u16 value from a location not u16-aligned.
  *
  * Note that unaligned accesses can be very expensive on some architectures.
@@ -129,8 +129,8 @@
  * @val: value to place
  * @ptr: pointer to location
  *
- * This macro should be used for placing values larger in size than 
- * single bytes at locations that are expected to be improperly aligned, 
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
  * e.g. writing a u16 value to a location not u16-aligned.
  *
  * Note that unaligned accesses can be very expensive on some architectures.
diff -urN linux-2.4.20-pre6/include/asm-mips/vr41xx/capcella.h linux-2.4.20-pre7/include/asm-mips/vr41xx/capcella.h
--- linux-2.4.20-pre6/include/asm-mips/vr41xx/capcella.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/vr41xx/capcella.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,61 @@
+/*
+ * FILE NAME
+ *	include/asm-mips/vr41xx/capcella.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for ZAO Networks Capcella.
+ *
+ * Copyright 2002 Yoichi Yuasa
+ *                yuasa@hh.iij4u.or.jp
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the 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 __ZAO_CAPCELLA_H
+#define __ZAO_CAPCELLA_H
+
+#include <asm/addrspace.h>
+#include <asm/vr41xx/vr41xx.h>
+
+/*
+ * Board specific address mapping
+ */
+#define VR41XX_PCI_MEM1_BASE		0x10000000
+#define VR41XX_PCI_MEM1_SIZE		0x04000000
+#define VR41XX_PCI_MEM1_MASK		0x7c000000
+
+#define VR41XX_PCI_MEM2_BASE		0x14000000
+#define VR41XX_PCI_MEM2_SIZE		0x02000000
+#define VR41XX_PCI_MEM2_MASK		0x7e000000
+
+#define VR41XX_PCI_IO_BASE		0x16000000
+#define VR41XX_PCI_IO_SIZE		0x02000000
+#define VR41XX_PCI_IO_MASK		0x7e000000
+
+#define VR41XX_PCI_IO_START		0x01000000
+#define VR41XX_PCI_IO_END		0x01ffffff
+
+#define VR41XX_PCI_MEM_START		0x12000000
+#define VR41XX_PCI_MEM_END		0x15ffffff
+
+#define IO_PORT_BASE			KSEG1ADDR(VR41XX_PCI_IO_BASE)
+#define IO_PORT_RESOURCE_START		0
+#define IO_PORT_RESOURCE_END		VR41XX_PCI_IO_SIZE
+#define IO_MEM1_RESOURCE_START		VR41XX_PCI_MEM1_BASE
+#define IO_MEM1_RESOURCE_END		(VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE)
+#define IO_MEM2_RESOURCE_START		VR41XX_PCI_MEM2_BASE
+#define IO_MEM2_RESOURCE_END		(VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE)
+
+/*
+ * Interrupt Number
+ */
+#define RTL8139_1_IRQ			GIU_IRQ(4)
+#define RTL8139_2_IRQ			GIU_IRQ(5)
+#define PC104PLUS_INTA_IRQ		GIU_IRQ(2)
+#define PC104PLUS_INTB_IRQ		GIU_IRQ(3)
+#define PC104PLUS_INTC_IRQ		GIU_IRQ(4)
+#define PC104PLUS_INTD_IRQ		GIU_IRQ(5)
+
+#endif /* __ZAO_CAPCELLA_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/vr41xx/eagle.h linux-2.4.20-pre7/include/asm-mips/vr41xx/eagle.h
--- linux-2.4.20-pre6/include/asm-mips/vr41xx/eagle.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/vr41xx/eagle.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,275 @@
+/*
+ * FILE NAME
+ *	include/asm-mips/vr41xx/eagle.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for NEC Eagle board.
+ *
+ * Author: MontaVista Software, Inc.
+ *         yyuasa@mvista.com or source@mvista.com
+ *
+ * Copyright 2001,2002 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 __NEC_EAGLE_H
+#define __NEC_EAGLE_H
+
+#include <asm/addrspace.h>
+#include <asm/vr41xx/vr41xx.h>
+
+/*
+ * Board specific address mapping
+ */
+#define VR41XX_PCI_MEM1_BASE		0x10000000
+#define VR41XX_PCI_MEM1_SIZE		0x04000000
+#define VR41XX_PCI_MEM1_MASK		0x7c000000
+
+#define VR41XX_PCI_MEM2_BASE		0x14000000
+#define VR41XX_PCI_MEM2_SIZE		0x02000000
+#define VR41XX_PCI_MEM2_MASK		0x7e000000
+
+#define VR41XX_PCI_IO_BASE		0x16000000
+#define VR41XX_PCI_IO_SIZE		0x02000000
+#define VR41XX_PCI_IO_MASK		0x7e000000
+
+#define VR41XX_PCI_IO_START		0x01000000
+#define VR41XX_PCI_IO_END		0x01ffffff
+
+#define VR41XX_PCI_MEM_START		0x12000000
+#define VR41XX_PCI_MEM_END		0x15ffffff
+
+#define IO_PORT_BASE			KSEG1ADDR(VR41XX_PCI_IO_BASE)
+#define IO_PORT_RESOURCE_START		0
+#define IO_PORT_RESOURCE_END		VR41XX_PCI_IO_SIZE
+#define IO_MEM1_RESOURCE_START		VR41XX_PCI_MEM1_BASE
+#define IO_MEM1_RESOURCE_END		(VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE)
+#define IO_MEM2_RESOURCE_START		VR41XX_PCI_MEM2_BASE
+#define IO_MEM2_RESOURCE_END		(VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE)
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define VRC4173_PIN			1
+#define PCISLOT_PIN			4
+#define FPGA_PIN			5
+#define DCD_PIN				15
+
+/*
+ * Interrupt Number
+ */
+#define VRC4173_CASCADE_IRQ		GIU_IRQ(VRC4173_PIN)
+#define PCISLOT_IRQ			GIU_IRQ(PCISLOT_PIN)
+#define FPGA_CASCADE_IRQ		GIU_IRQ(FPGA_PIN)
+#define DCD_IRQ				GIU_IRQ(DCD_PIN)
+
+#define SDBINT_IRQ_BASE			89
+#define DEG_IRQ				(SDBINT_IRQ_BASE + 1)
+#define ENUM_IRQ			(SDBINT_IRQ_BASE + 2)
+#define SIO1INT_IRQ			(SDBINT_IRQ_BASE + 3)
+#define SIO2INT_IRQ			(SDBINT_IRQ_BASE + 4)
+#define PARINT_IRQ			(SDBINT_IRQ_BASE + 5)
+#define SDBINT_IRQ_LAST			PARINT_IRQ
+
+#define PCIINT_IRQ_BASE			97
+#define CP_INTA_IRQ			(PCIINT_IRQ_BASE + 0)
+#define CP_INTB_IRQ			(PCIINT_IRQ_BASE + 1)
+#define CP_INTC_IRQ			(PCIINT_IRQ_BASE + 2)
+#define CP_INTD_IRQ			(PCIINT_IRQ_BASE + 3)
+#define LANINTA_IRQ			(PCIINT_IRQ_BASE + 4)
+#define PCIINT_IRQ_LAST			LANINTA_IRQ
+
+
+/*
+ * On board Devices I/O Mapping
+ */
+#define NEC_EAGLE_SIO1RB		KSEG1ADDR(0x0DFFFEC0)
+#define NEC_EAGLE_SIO1TH		KSEG1ADDR(0x0DFFFEC0)
+#define NEC_EAGLE_SIO1IE		KSEG1ADDR(0x0DFFFEC2)
+#define NEC_EAGLE_SIO1IID		KSEG1ADDR(0x0DFFFEC4)
+#define NEC_EAGLE_SIO1FC		KSEG1ADDR(0x0DFFFEC4)
+#define NEC_EAGLE_SIO1LC		KSEG1ADDR(0x0DFFFEC6)
+#define NEC_EAGLE_SIO1MC		KSEG1ADDR(0x0DFFFEC8)
+#define NEC_EAGLE_SIO1LS		KSEG1ADDR(0x0DFFFECA)
+#define NEC_EAGLE_SIO1MS		KSEG1ADDR(0x0DFFFECC)
+#define NEC_EAGLE_SIO1SC		KSEG1ADDR(0x0DFFFECE)
+
+#define NEC_EAGLE_SIO2TH		KSEG1ADDR(0x0DFFFED0)
+#define NEC_EAGLE_SIO2IE		KSEG1ADDR(0x0DFFFED2)
+#define NEC_EAGLE_SIO2IID		KSEG1ADDR(0x0DFFFED4)
+#define NEC_EAGLE_SIO2FC		KSEG1ADDR(0x0DFFFED4)
+#define NEC_EAGLE_SIO2LC		KSEG1ADDR(0x0DFFFED6)
+#define NEC_EAGLE_SIO2MC		KSEG1ADDR(0x0DFFFED8)
+#define NEC_EAGLE_SIO2LS		KSEG1ADDR(0x0DFFFEDA)
+#define NEC_EAGLE_SIO2MS		KSEG1ADDR(0x0DFFFEDC)
+#define NEC_EAGLE_SIO2SC		KSEG1ADDR(0x0DFFFEDE)
+
+#define NEC_EAGLE_PIOPP_DATA		KSEG1ADDR(0x0DFFFEE0)
+#define NEC_EAGLE_PIOPP_STATUS		KSEG1ADDR(0x0DFFFEE2)
+#define NEC_EAGLE_PIOPP_CNT		KSEG1ADDR(0x0DFFFEE4)
+#define NEC_EAGLE_PIOPP_EPPADDR		KSEG1ADDR(0x0DFFFEE6)
+#define NEC_EAGLE_PIOPP_EPPDATA0	KSEG1ADDR(0x0DFFFEE8)
+#define NEC_EAGLE_PIOPP_EPPDATA1	KSEG1ADDR(0x0DFFFEEA)
+#define NEC_EAGLE_PIOPP_EPPDATA2	KSEG1ADDR(0x0DFFFEEC)
+
+#define NEC_EAGLE_PIOECP_DATA		KSEG1ADDR(0x0DFFFEF0)
+#define NEC_EAGLE_PIOECP_CONFIG		KSEG1ADDR(0x0DFFFEF2)
+#define NEC_EAGLE_PIOECP_EXTCNT		KSEG1ADDR(0x0DFFFEF4)
+
+
+/*
+ *  FLSHCNT Register
+ */
+#define NEC_EAGLE_FLSHCNT		KSEG1ADDR(0x0DFFFFA0)
+#define NEC_EAGLE_FLSHCNT_FRDY		0x80
+#define NEC_EAGLE_FLSHCNT_VPPE		0x40
+#define NEC_EAGLE_FLSHCNT_WP2		0x01
+
+
+/*
+ * FLSHBANK Register
+ */
+#define NEC_EAGLE_FLSHBANK		KSEG1ADDR(0x0DFFFFA4)
+#define NEC_EAGLE_FLSHBANK_S_BANK2	0x40
+#define NEC_EAGLE_FLSHBANK_S_BANK1	0x20
+#define NEC_EAGLE_FLSHBANK_BNKQ4	0x10
+#define NEC_EAGLE_FLSHBANK_BNKQ3	0x08
+#define NEC_EAGLE_FLSHBANK_BNKQ2	0x04
+#define NEC_EAGLE_FLSHBANK_BNKQ1	0x02
+#define NEC_EAGLE_FLSHBANK_BNKQ0	0x01
+
+
+/*
+ * SWITCH Setting Register
+ */
+#define NEC_EAGLE_SWTCHSET		KSEG1ADDR(0x0DFFFFA8)
+#define NEC_EAGLE_SWTCHSET_DP2SW4	0x80
+#define NEC_EAGLE_SWTCHSET_DP2SW3	0x40
+#define NEC_EAGLE_SWTCHSET_DP2SW2	0x20
+#define NEC_EAGLE_SWTCHSET_DP2SW1	0x10
+#define NEC_EAGLE_SWTCHSET_DP1SW4	0x08
+#define NEC_EAGLE_SWTCHSET_DP1SW3	0x04
+#define NEC_EAGLE_SWTCHSET_DP1SW2	0x02
+#define NEC_EAGLE_SWTCHSET_DP1SW1	0x01
+
+
+/*
+ * PPT Parallel Port Device Controller
+ */
+#define NEC_EAGLE_PPT_WRITE_DATA	KSEG1ADDR(0x0DFFFFB0)
+#define NEC_EAGLE_PPT_READ_DATA		KSEG1ADDR(0x0DFFFFB2)
+#define NEC_EAGLE_PPT_CNT		KSEG1ADDR(0x0DFFFFB4)
+#define NEC_EAGLE_PPT_CNT2		KSEG1ADDR(0x0DFFFFB4)
+
+/* Control Register */
+#define NEC_EAGLE_PPT_INTMSK		0x20
+#define NEC_EAGLE_PPT_PARIINT		0x10
+#define NEC_EAGLE_PPT_SELECTIN		0x08
+#define NEC_EAGLE_PPT_INIT		0x04
+#define NEC_EAGLE_PPT_AUTOFD		0x02
+#define NEC_EAGLE_PPT_STROBE		0x01
+
+/* Control Rgister 2 */
+#define NEC_EAGLE_PPT_PAREN		0x80
+#define NEC_EAGLE_PPT_AUTOEN		0x20
+#define NEC_EAGLE_PPT_BUSY		0x10
+#define NEC_EAGLE_PPT_ACK		0x08
+#define NEC_EAGLE_PPT_PE		0x04
+#define NEC_EAGLE_PPT_SELECT		0x02
+#define NEC_EAGLE_PPT_FAULT		0x01
+
+
+/*
+ * LEDWR Register
+ */
+#define NEC_EAGLE_LEDWR1		KSEG1ADDR(0x0DFFFFC0)
+#define NEC_EAGLE_LEDWR2		KSEG1ADDR(0x0DFFFFC4)
+
+
+/*
+ * SDBINT Register
+ */
+#define NEC_EAGLE_SDBINT		KSEG1ADDR(0x0DFFFFD0)
+#define NEC_EAGLE_SDBINT_PARINT		0x20
+#define NEC_EAGLE_SDBINT_SIO2INT	0x10
+#define NEC_EAGLE_SDBINT_SIO1INT	0x08
+#define NEC_EAGLE_SDBINT_ENUM		0x04
+#define NEC_EAGLE_SDBINT_DEG		0x02
+
+
+/*
+ * SDB INTMSK Register
+ */
+#define NEC_EAGLE_SDBINTMSK		KSEG1ADDR(0x0DFFFFD4)
+#define NEC_EAGLE_SDBINTMSK_MSKPAR	0x20
+#define NEC_EAGLE_SDBINTMSK_MSKSIO2	0x10
+#define NEC_EAGLE_SDBINTMSK_MSKSIO1	0x08
+#define NEC_EAGLE_SDBINTMSK_MSKENUM	0x04
+#define NEC_EAGLE_SDBINTMSK_MSKDEG	0x02
+
+
+/*
+ * RSTREG Register
+ */
+#define NEC_EAGLE_RSTREG		KSEG1ADDR(0x0DFFFFD8)
+#define NEC_EAGLE_RST_RSTSW		0x02
+#define NEC_EAGLE_RST_LEDOFF		0x01
+
+
+/*
+ * PCI INT Rgister
+ */
+#define NEC_EAGLE_PCIINTREG		KSEG1ADDR(0x0DFFFFDC)
+#define NEC_EAGLE_PCIINT_LANINT		0x10
+#define NEC_EAGLE_PCIINT_CP_INTD	0x08
+#define NEC_EAGLE_PCIINT_CP_INTC	0x04
+#define NEC_EAGLE_PCIINT_CP_INTB	0x02
+#define NEC_EAGLE_PCIINT_CP_INTA	0x01
+
+
+/*
+ * PCI INT Mask Register
+ */
+#define NEC_EAGLE_PCIINTMSKREG		KSEG1ADDR(0x0DFFFFE0)
+#define NEC_EAGLE_PCIINTMSK_MSKLANINT	0x10
+#define NEC_EAGLE_PCIINTMSK_MSKCP_INTD	0x08
+#define NEC_EAGLE_PCIINTMSK_MSKCP_INTC	0x04
+#define NEC_EAGLE_PCIINTMSK_MSKCP_INTB	0x02
+#define NEC_EAGLE_PCIINTMSK_MSKCP_INTA	0x01
+
+
+/*
+ * CLK Division Register
+ */
+#define NEC_EAGLE_CLKDIV		KSEG1ADDR(0x0DFFFFE4)
+#define NEC_EAGLE_CLKDIV_PCIDIV1	0x10
+#define NEC_EAGLE_CLKDIV_PCIDIV0	0x08
+#define NEC_EAGLE_CLKDIV_VTDIV2		0x04
+#define NEC_EAGLE_CLKDIV_VTDIV1		0x02
+#define NEC_EAGLE_CLKDIV_VTDIV0		0x01
+
+
+/*
+ * Source Revision Register
+ */
+#define NEC_EAGLE_REVISION		KSEG1ADDR(0x0DFFFFE8)
+
+#endif /* __NEC_EAGLE_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/vr41xx/vr41xx.h linux-2.4.20-pre7/include/asm-mips/vr41xx/vr41xx.h
--- linux-2.4.20-pre6/include/asm-mips/vr41xx/vr41xx.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips/vr41xx/vr41xx.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,148 @@
+/*
+ * include/asm-mips/vr41xx/vr41xx.h
+ *
+ * Include file for NEC VR4100 series.
+ *
+ * Copyright (C) 1999 Michael Klar
+ * Copyright (C) 2001, 2002 Paul Mundt
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2002 TimeSys 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 __NEC_VR41XX_H
+#define __NEC_VR41XX_H
+
+#include <linux/interrupt.h>
+
+/*
+ * CPU Revision
+ */
+/* VR4122 0x00000c70-0x00000c72 */
+#define PRID_VR4122_REV1_0	0x00000c70
+#define PRID_VR4122_REV2_0	0x00000c70
+#define PRID_VR4122_REV2_1	0x00000c70
+#define PRID_VR4122_REV3_0	0x00000c71
+#define PRID_VR4122_REV3_1	0x00000c72
+
+/* VR4181A 0x00000c73-0x00000c7f */
+#define PRID_VR4181A_REV1_0	0x00000c73
+#define PRID_VR4181A_REV1_1	0x00000c74
+
+/* VR4131 0x00000c80-0x00000c8f */
+#define PRID_VR4131_REV1_2	0x00000c80
+#define PRID_VR4131_REV2_0	0x00000c81
+#define PRID_VR4131_REV2_1	0x00000c82
+#define PRID_VR4131_REV2_2	0x00000c83
+
+
+/*
+ * Bus Control Uint
+ */
+extern void vr41xx_bcu_init(void);
+
+/*
+ * Clock Mask Unit
+ */
+extern void vr41xx_cmu_init(u16 mask);
+extern void vr41xx_clock_supply(u16 mask);
+extern void vr41xx_clock_mask(u16 mask);
+
+/*
+ * Interrupt Control Unit
+ */
+
+/* GIU Interrupt Numbers */
+#define GIU_IRQ(x)	(40 + (x))
+
+extern void (*board_irq_init)(void);
+extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq));
+
+/*
+ * Gegeral-Purpose I/O Unit
+ */
+enum {
+	TRIGGER_LEVEL,
+	TRIGGER_EDGE
+};
+
+enum {
+	SIGNAL_THROUGH,
+	SIGNAL_HOLD
+};
+
+extern void vr41xx_set_irq_trigger(u8 pin, u8 trigger, u8 hold);
+
+enum {
+	LEVEL_LOW,
+	LEVEL_HIGH
+};
+
+extern void vr41xx_set_irq_level(u8 pin, u8 level);
+
+enum {
+	PIO_INPUT,
+	PIO_OUTPUT
+};
+
+enum {
+	DATA_LOW,
+	DATA_HIGH
+};
+
+/*
+ * Serial Interface Unit
+ */
+extern void vr41xx_siu_init(int interface, int module);
+extern void vr41xx_siu_ifselect(int interface, int module);
+extern int vr41xx_serial_ports;
+
+/* SIU interfaces */
+enum {
+	SIU_RS232C,
+	SIU_IRDA
+};
+
+/* IrDA interfaces */
+enum {
+	IRDA_SHARP = 1,
+	IRDA_TEMIC,
+	IRDA_HP
+};
+
+/*
+ * Debug Serial Interface Unit
+ */
+extern void vr41xx_dsiu_init(void);
+
+/*
+ * PCI Control Unit
+ */
+struct vr41xx_pci_address_space {
+	u32 internal_base;
+	u32 address_mask;
+	u32 pci_base;
+};
+
+struct vr41xx_pci_address_map {
+	struct vr41xx_pci_address_space *mem1;
+	struct vr41xx_pci_address_space *mem2;
+	struct vr41xx_pci_address_space *io;
+};
+
+extern void vr41xx_pciu_init(struct vr41xx_pci_address_map *map);
+
+/*
+ * MISC
+ */
+extern void vr41xx_time_init(void);
+extern void vr41xx_timer_setup(struct irqaction *irq);
+
+extern void vr41xx_restart(char *command);
+extern void vr41xx_halt(void);
+extern void vr41xx_power_off(void);
+
+#endif /* __NEC_VR41XX_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/war.h linux-2.4.20-pre7/include/asm-mips/war.h
--- linux-2.4.20-pre6/include/asm-mips/war.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/war.h	Thu Sep 12 20:01:49 2002
@@ -8,6 +8,8 @@
 #ifndef _ASM_WAR_H
 #define _ASM_WAR_H
 
+#include <linux/config.h>
+
 /*
  * Pleassures of the R4600 V1.x.  Cite from the IDT R4600 V1.7 errata:
  *
@@ -15,10 +17,10 @@
  *      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 
+ *      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 
+ *      four instructions that are not any kind of load or store
  *      instruction.
  *
  *      This is not allowed:    lw
@@ -50,4 +52,19 @@
  */
 #define R4600_V2_HIT_CACHEOP_WAR
 
+#ifdef CONFIG_CPU_R5432
+
+/*
+ * When an interrupt happens on a CP0 register read instruction, CPU may
+ * lock up or read corrupted values of CP0 registers after it enters
+ * the exception handler.
+ *
+ * This workaround makes sure that we read a "safe" CP0 register as the
+ * first thing in the exception handler, which breaks one of the
+ * pre-conditions for this problem.
+ */
+#define	R5432_CP0_INTERRUPT_WAR
+
+#endif
+
 #endif /* _ASM_WAR_H */
diff -urN linux-2.4.20-pre6/include/asm-mips/wbflush.h linux-2.4.20-pre7/include/asm-mips/wbflush.h
--- linux-2.4.20-pre6/include/asm-mips/wbflush.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips/wbflush.h	Thu Sep 12 20:01:49 2002
@@ -6,29 +6,30 @@
  * for more details.
  *
  * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
  */
 #ifndef __ASM_MIPS_WBFLUSH_H
 #define __ASM_MIPS_WBFLUSH_H
 
 #include <linux/config.h>
 
-#if defined(CONFIG_CPU_HAS_WB)
-/*
- * R2000 or R3000
- */
-extern void (*__wbflush) (void);
+#ifdef CONFIG_CPU_HAS_WB
 
-#define wbflush() __wbflush()
+extern void (*__wbflush)(void);
+extern void wbflush_setup(void);
 
-#else
-/*
- * we don't need no stinkin' wbflush
- */
+#define wbflush()			\
+	do {				\
+		__sync();		\
+		__wbflush();		\
+	} while (0)
 
-#define wbflush()  do { } while(0)
+#else /* !CONFIG_CPU_HAS_WB */
 
-#endif
+#define wbflush_setup() do { } while (0)
 
-extern void wbflush_setup(void);
+#define wbflush() fast_iob()
+
+#endif /* !CONFIG_CPU_HAS_WB */
 
 #endif /* __ASM_MIPS_WBFLUSH_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/a.out.h linux-2.4.20-pre7/include/asm-mips64/a.out.h
--- linux-2.4.20-pre6/include/asm-mips64/a.out.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/a.out.h	Thu Sep 12 20:01:49 2002
@@ -26,7 +26,7 @@
 
 #ifdef __KERNEL__
 
-#define STACK_TOP (current->thread.mflags & MF_32BIT ? 0x7fff8000 : TASK_SIZE)
+#define STACK_TOP (current->thread.mflags & MF_32BIT ? TASK_SIZE32 : TASK_SIZE)
 
 #endif
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/addrspace.h linux-2.4.20-pre7/include/asm-mips64/addrspace.h
--- linux-2.4.20-pre6/include/asm-mips64/addrspace.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/addrspace.h	Thu Sep 12 20:01:49 2002
@@ -85,7 +85,8 @@
 #if defined (CONFIG_CPU_R4300)						\
     || defined (CONFIG_CPU_R4X00)					\
     || defined (CONFIG_CPU_R5000)					\
-    || defined (CONFIG_CPU_NEVADA)
+    || defined (CONFIG_CPU_NEVADA)					\
+    || defined (CONFIG_CPU_MIPS64)
 #define	KUSIZE			0x0000010000000000	/* 2^^40 */
 #define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
 #define	K0SIZE			0x0000001000000000	/* 2^^36 */
diff -urN linux-2.4.20-pre6/include/asm-mips64/asm.h linux-2.4.20-pre7/include/asm-mips64/asm.h
--- linux-2.4.20-pre6/include/asm-mips64/asm.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/asm.h	Thu Sep 12 20:01:49 2002
@@ -88,7 +88,7 @@
 #define	PANIC(msg)                                      \
 		.set	push;				\
 		.set	reorder;                        \
-		la	a0,8f;                          \
+		PTR_LA	a0,8f;                          \
 		jal	panic;                          \
 9:		b	9b;                             \
 		.set	pop;				\
@@ -100,7 +100,7 @@
 #define PRINT(string)                                   \
 		.set	push;				\
 		.set	reorder;                        \
-		la	a0,8f;                          \
+		PTR_LA	a0,8f;                          \
 		jal	printk;                         \
 		.set	pop;				\
 		TEXT(string)
@@ -165,7 +165,7 @@
 		.set	push;				\
 		.set	reorder;			\
 		bnez	rt,9f;                          \
-		move	rd,rt;                          \
+		move	rd,rs;                          \
 		.set	pop;				\
 9:
 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
diff -urN linux-2.4.20-pre6/include/asm-mips64/asmmacro.h linux-2.4.20-pre7/include/asm-mips64/asmmacro.h
--- linux-2.4.20-pre6/include/asm-mips64/asmmacro.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/asmmacro.h	Thu Sep 12 20:01:49 2002
@@ -8,8 +8,22 @@
 #ifndef _ASM_ASMMACRO_H
 #define _ASM_ASMMACRO_H
 
+#include <linux/config.h>
 #include <asm/offset.h>
 
+#ifdef CONFIG_CPU_SB1
+#define FPU_ENABLE_HAZARD		\
+	.set    push;			\
+	.set	noreorder;		\
+	.set    mips2;			\
+	SSNOP;				\
+	bnezl   $0, .+4;		\
+	 SSNOP;				\
+	.set    pop
+#else
+#define FPU_ENABLE_HAZARD
+#endif
+
 	.macro	fpu_save_16even thread tmp
 	cfc1	\tmp, fcr31
 	sdc1	$f2,  (THREAD_FPU + 0x010)(\thread)
diff -urN linux-2.4.20-pre6/include/asm-mips64/bcache.h linux-2.4.20-pre7/include/asm-mips64/bcache.h
--- linux-2.4.20-pre6/include/asm-mips64/bcache.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/bcache.h	Thu Sep 12 20:01:49 2002
@@ -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);
diff -urN linux-2.4.20-pre6/include/asm-mips64/bitops.h linux-2.4.20-pre7/include/asm-mips64/bitops.h
--- linux-2.4.20-pre6/include/asm-mips64/bitops.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/bitops.h	Thu Sep 12 20:01:49 2002
@@ -132,7 +132,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 static inline unsigned long test_and_set_bit(unsigned long nr,
@@ -164,7 +164,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -186,7 +186,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 static inline unsigned long test_and_clear_bit(unsigned long nr,
@@ -219,7 +219,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -241,7 +241,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
  * It also implies a memory barrier.
  */
 static inline unsigned long test_and_change_bit(unsigned long nr,
@@ -273,7 +273,7 @@
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This operation is non-atomic and can be reordered.  
+ * This operation is non-atomic and can be reordered.
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
@@ -599,7 +599,7 @@
 #define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
 #define ext2_find_next_zero_bit(addr, size, offset) \
                 find_next_zero_bit((addr), (size), (offset))
- 
+
 #endif /* !(__MIPSEB__) */
 
 /*
diff -urN linux-2.4.20-pre6/include/asm-mips64/bootinfo.h linux-2.4.20-pre7/include/asm-mips64/bootinfo.h
--- linux-2.4.20-pre6/include/asm-mips64/bootinfo.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/bootinfo.h	Thu Sep 12 20:01:49 2002
@@ -49,7 +49,7 @@
 #define MACH_OLIVETTI_M700      2	/* Olivetti M700-10 (-15 ??)    */
 
 /*
- * Valid machtype for group DEC 
+ * Valid machtype for group DEC
  */
 #define MACH_DSUNKNOWN		0
 #define MACH_DS23100		1	/* DECstation 2100 or 3100	*/
@@ -96,10 +96,11 @@
 /*
  * 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 */
+#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 */
+#define MACH_NEC_ROCKHOPPERII	4	/* Rockhopper II base board */
 
 /*
  * Valid machtype for group BAGET
@@ -121,17 +122,18 @@
 /*
  * Valid machtype for group MOMENCO
  */
-#define MACH_MOMENCO_OCELOT	0
- 
+#define MACH_MOMENCO_OCELOT		0
+#define MACH_MOMENCO_OCELOT_G		1
+
 /*
  * 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 */
+#define MACH_IVR		0	/* IVR eval board */
 
 /*
  * Valid machtype for group PHILIPS
@@ -150,18 +152,21 @@
 #define MACH_PALLAS		0
 #define MACH_TOPAS		1
 #define MACH_JMR		2
-#define MACH_TOSHIBA_JMR3927    3      /* JMR-TX3927 CPU/IO board */
+#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 MACH_PB1000		0	/* Au1000-based eval board */
+#define MACH_PB1100		1	/* Au1100-based eval board */
+#define MACH_PB1500		2	/* Au1500-based eval board */
+
 /*
  * Valid machtype for group NEC_VR41XX
  */
-#define MACH_NEC_OSPREY                0       /* Osprey eval board */
+#define MACH_NEC_OSPREY		0	/* Osprey eval board */
+#define MACH_NEC_EAGLE		1	/* NEC Eagle/Hawk board */
+#define MACH_ZAO_CAPCELLA	2	/* ZAO Networks Capcella */
 
 #define CL_SIZE			(256)
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/cache.h linux-2.4.20-pre7/include/asm-mips64/cache.h
--- linux-2.4.20-pre6/include/asm-mips64/cache.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/cache.h	Thu Sep 12 20:01:49 2002
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1997, 98, 99, 2000 Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
 #ifndef _ASM_CACHE_H
@@ -23,7 +23,17 @@
 };
 #endif /* !__ASSEMBLY__ */
 
-/* bytes per L1 cache line */
-#define L1_CACHE_BYTES		(1 << CONFIG_L1_CACHE_SHIFT)
+/*
+ * Flag definitions
+ */
+#define MIPS_CACHE_NOT_PRESENT 0x00000001
+
+#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 */
+#endif
+
+#define SMP_CACHE_BYTES		L1_CACHE_BYTES
 
 #endif /* _ASM_CACHE_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/checksum.h linux-2.4.20-pre7/include/asm-mips64/checksum.h
--- linux-2.4.20-pre6/include/asm-mips64/checksum.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/checksum.h	Thu Sep 12 20:01:49 2002
@@ -87,7 +87,7 @@
 
  	return sum;
 }
- 
+
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
  *	which always checksum on 4 octet boundaries.
@@ -202,7 +202,7 @@
 						     struct in6_addr *daddr,
 						     __u32 len,
 						     unsigned short proto,
-						     unsigned int sum) 
+						     unsigned int sum)
 {
 	__asm__(
 	".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t"
diff -urN linux-2.4.20-pre6/include/asm-mips64/cpu.h linux-2.4.20-pre7/include/asm-mips64/cpu.h
--- linux-2.4.20-pre6/include/asm-mips64/cpu.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/cpu.h	Thu Sep 12 20:01:49 2002
@@ -9,8 +9,8 @@
 
 #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 
+/* 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:
 
@@ -21,7 +21,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.  
+   spec.
 */
 
 #define PRID_COMP_LEGACY       0x000000
@@ -87,6 +87,12 @@
 #define PRID_REV_TX3912 	0x0010
 #define PRID_REV_TX3922 	0x0030
 #define PRID_REV_TX3927 	0x0040
+#define PRID_REV_VR4111		0x0050
+#define PRID_REV_VR4181		0x0050	/* Same as VR4111 */
+#define PRID_REV_VR4121		0x0060
+#define PRID_REV_VR4122		0x0070
+#define PRID_REV_VR4181A	0x0070	/* Same as VR4122 */
+#define PRID_REV_VR4131		0x0080
 
 /*
  * FPU implementation/revision register (CP1 control register 0).
@@ -100,6 +106,10 @@
 #define FPIR_IMP_NONE		0x0000
 
 #ifndef __ASSEMBLY__
+
+extern void cpu_probe(void);
+extern void cpu_report(void);
+
 /*
  * Capability and feature descriptor structure for MIPS CPU
  */
@@ -128,7 +138,8 @@
 	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
+	CPU_VR4111, CPU_VR4121, CPU_VR4122, CPU_VR4131, CPU_VR4181, CPU_VR4181A,
+	CPU_AU1100, CPU_LAST
 };
 
 #endif /* !__ASSEMBLY__ */
diff -urN linux-2.4.20-pre6/include/asm-mips64/delay.h linux-2.4.20-pre7/include/asm-mips64/delay.h
--- linux-2.4.20-pre6/include/asm-mips64/delay.h	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/include/asm-mips64/delay.h	Thu Sep 12 20:01:49 2002
@@ -11,6 +11,7 @@
 #define _ASM_DELAY_H
 
 #include <linux/config.h>
+#include <asm/param.h>
 
 extern unsigned long loops_per_jiffy;
 
@@ -40,7 +41,11 @@
 {
 	unsigned long lo;
 
+#if (HZ == 100)
 	usecs *= 0x00068db8bac710cbUL;		/* 2**64 / (1000000 / HZ) */
+#elif (HZ == 128)
+	usecs *= 0x0008637bd05af6c6UL;		/* 2**64 / (1000000 / HZ) */
+#endif
 	__asm__("dmultu\t%2,%3"
 		:"=h" (usecs), "=l" (lo)
 		:"r" (usecs),"r" (lpj));
diff -urN linux-2.4.20-pre6/include/asm-mips64/dma.h linux-2.4.20-pre7/include/asm-mips64/dma.h
--- linux-2.4.20-pre6/include/asm-mips64/dma.h	Wed Jul 12 15:15:10 2000
+++ linux-2.4.20-pre7/include/asm-mips64/dma.h	Thu Sep 12 20:01:49 2002
@@ -43,7 +43,7 @@
  *  - 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
  *
- * DMA transfers are limited to the lower 16MB of _physical_ memory.  
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.
  * Note that addresses loaded into registers must be _physical_ addresses,
  * not logical addresses (which may differ if paging is active).
  *
@@ -53,7 +53,7 @@
  *    |  ...  |   |  ... |   |  ... |
  *    |  ...  |   |  ... |   |  ... |
  *    |  ...  |   |  ... |   |  ... |
- *   P7  ...  P0  A7 ... A0  A7 ... A0   
+ *   P7  ...  P0  A7 ... A0  A7 ... A0
  * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
  *
  *  Address mapping for channels 5-7:
@@ -62,7 +62,7 @@
  *    |  ...  |   \   \   ... \  \  \  ... \  \
  *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
  *    |  ...  |     \   \   ... \  \  \  ... \
- *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+ *   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
@@ -71,7 +71,7 @@
  *
  * 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. 
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation.
  *
  */
 
@@ -83,7 +83,13 @@
  * Deskstations or Acer PICA but not the much more versatile DMA logic used
  * for the local devices on Acer PICA or Magnums.
  */
+#ifdef CONFIG_SGI_IP22
+/* Horrible hack to have a correct DMA window on IP22 */
+#include <asm/sgi/sgimc.h>
+#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000)
+#else
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + 0x01000000)
+#endif
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
@@ -142,6 +148,7 @@
 #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;
 
@@ -286,7 +293,7 @@
 
 	count = 1 + dma_inb(io_port);
 	count += dma_inb(io_port) << 8;
-	
+
 	return (dmanr<=3)? count : (count<<1);
 }
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/elf.h linux-2.4.20-pre7/include/asm-mips64/elf.h
--- linux-2.4.20-pre6/include/asm-mips64/elf.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/elf.h	Thu Sep 12 20:01:49 2002
@@ -9,21 +9,23 @@
 #include <asm/ptrace.h>
 #include <asm/user.h>
 
-#ifndef ELF_ARCH
-/* ELF register definitions */
-#define ELF_NGREG	45
-#define ELF_NFPREG	33
-
-/* ELF header e_flags defines. MIPS architecture level. */
+/* 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.  */
+#define EF_MIPS_ARCH_32     0x50000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64     0x60000000  /* MIPS64 code.  */
+/* The ABI of a file. */
+#define EF_MIPS_ABI_O32     0x00001000  /* O32 ABI.  */
+#define EF_MIPS_ABI_O64     0x00002000  /* O32 extended for 64 bit.  */
+
+#ifndef ELF_ARCH
+/* ELF register definitions */
+#define ELF_NGREG	45
+#define ELF_NFPREG	33
 
 typedef unsigned long elf_greg_t;
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
@@ -41,14 +43,9 @@
 									\
 	if (__h->e_machine != EM_MIPS)					\
 		__res = 0;						\
-	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;						\
+	if ((__h->e_ident[EI_CLASS] == ELFCLASS32) &&			\
+	    ((__h->e_flags & EF_MIPS_ABI2) == 0))			\
+		__res = 0;						\
 									\
 	__res;								\
 })
diff -urN linux-2.4.20-pre6/include/asm-mips64/exception.h linux-2.4.20-pre7/include/asm-mips64/exception.h
--- linux-2.4.20-pre6/include/asm-mips64/exception.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/exception.h	Thu Sep 12 20:01:49 2002
@@ -70,7 +70,7 @@
 	__BUILD_\verbose \exception
 	move	a0, sp
 	jal	do_\handler
-	j	ret_from_sys_call
+	j	ret_from_exception
 	 nop
 	END(handle_\exception)
 	.endm
diff -urN linux-2.4.20-pre6/include/asm-mips64/fcntl.h linux-2.4.20-pre7/include/asm-mips64/fcntl.h
--- linux-2.4.20-pre6/include/asm-mips64/fcntl.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/fcntl.h	Thu Sep 12 20:01:49 2002
@@ -67,7 +67,7 @@
 /* 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		XXXXXXXXXXXXXXXXXX
+#define LOCK_NB		4	/* or'd with one of the above to prevent
 				   blocking */
 #define LOCK_UN		8	/* remove lock */
 
@@ -81,12 +81,23 @@
 	short l_whence;
 	__kernel_off_t l_start;
 	__kernel_off_t l_len;
-	long  l_sysid;			/* XXXXXXXXXXXXXXXXXXXXXXXXX */
+	long  l_sysid;
 	__kernel_pid_t l_pid;
-	long  pad[4];			/* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
+	long  pad[4];
 } flock_t;
 
 #ifdef __KERNEL__
+struct flock32 {				/* for 32-bit compat code */
+	short	l_type;
+	short	l_whence;
+	__kernel_off_t32 l_start;
+	__kernel_off_t32 l_len;
+	__s32	l_sysid;
+	__kernel_pid_t32 l_pid;
+	short	__unused;
+	__s32	pad[4];
+};
+
 #define flock64		flock
 #endif
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/gdb-stub.h linux-2.4.20-pre7/include/asm-mips64/gdb-stub.h
--- linux-2.4.20-pre6/include/asm-mips64/gdb-stub.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/gdb-stub.h	Thu Sep 12 20:01:49 2002
@@ -57,7 +57,7 @@
 #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
  */
@@ -180,7 +180,7 @@
 	 */
 	long	frame_ptr;
 	long    dummy;		/* unused */
-	
+
 	/*
 	 * saved cp0 registers
 	 */
diff -urN linux-2.4.20-pre6/include/asm-mips64/gfx.h linux-2.4.20-pre7/include/asm-mips64/gfx.h
--- linux-2.4.20-pre6/include/asm-mips64/gfx.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/gfx.h	Thu Sep 12 20:01:49 2002
@@ -6,7 +6,7 @@
  * This is the user-visible SGI GFX interface.
  *
  * This must be used verbatim into the GNU libc.  It does not include
- * any kernel-only bits on it.  
+ * any kernel-only bits on it.
  *
  * miguel@nuclecu.unam.mx
  */
diff -urN linux-2.4.20-pre6/include/asm-mips64/gt64120.h linux-2.4.20-pre7/include/asm-mips64/gt64120.h
--- linux-2.4.20-pre6/include/asm-mips64/gt64120.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/gt64120.h	Thu Sep 12 20:01:49 2002
@@ -60,7 +60,7 @@
 #define GT_PCI1M0REMAP_OFS	0x110
 #define GT_PCI1M1REMAP_OFS	0x118
 
-#define GT_SCS0LD_OFS		0x400	
+#define GT_SCS0LD_OFS		0x400
 #define GT_SCS0HD_OFS		0x404
 #define GT_SCS1LD_OFS		0x408
 #define GT_SCS1HD_OFS		0x40c
@@ -324,7 +324,7 @@
 #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
diff -urN linux-2.4.20-pre6/include/asm-mips64/ide.h linux-2.4.20-pre7/include/asm-mips64/ide.h
--- linux-2.4.20-pre6/include/asm-mips64/ide.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/ide.h	Thu Sep 12 20:01:49 2002
@@ -18,6 +18,7 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <asm/io.h>
 
 #ifndef MAX_HWIFS
 # ifdef CONFIG_BLK_DEV_IDEPCI
@@ -79,11 +80,19 @@
 typedef union {
 	unsigned all			: 8;	/* all of the bits together */
 	struct {
+#ifdef __MIPSEB__
+		unsigned bit7           : 1;    /* always 1 */
+		unsigned lba            : 1;    /* using LBA instead of CHS */
+		unsigned bit5           : 1;    /* always 1 */
+		unsigned unit           : 1;    /* drive select number, 0 or 1 */
+		unsigned head           : 4;    /* always zeros here */
+#else
 		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 */
+#endif
 	} b;
 } select_t;
 
@@ -139,54 +148,142 @@
 
 #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
 
-#ifdef insl
-#undef insl
-#endif
-#ifdef outsl
-#undef outsl
-#endif
+/* 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(p,a,c)							\
-do {									\
-	unsigned short *ptr = (unsigned short *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		*ptr++ = inw(p);					\
-} while (0)
-#define insl(p,a,c)							\
-do {									\
-	unsigned long *ptr = (unsigned long *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		*ptr++ = inl(p);					\
-} while (0)
-#define outsw(p,a,c)							\
-do {									\
-	unsigned short *ptr = (unsigned short *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		outw(*ptr++, (p));					\
-} while (0)
-#define outsl(p,a,c) {							\
-	unsigned long *ptr = (unsigned long *)(a);			\
-	unsigned int i = (c);						\
-	while (i--)							\
-		outl(*ptr++, (p));					\
-} while (0)
+#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)
 
-#endif /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
+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 */
+#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;
+		};
+	}
+}
+
+#else /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
+
+#define ide_fix_driveid(id)		do {} while (0)
+
+#endif
 
 /*
  * The following are not needed for the non-m68k ports
  */
 #define ide_ack_intr(hwif)		(1)
-#define ide_fix_driveid(id)		do {} while (0)
 #define ide_release_lock(lock)		do {} while (0)
 #define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/io.h linux-2.4.20-pre7/include/asm-mips64/io.h
--- linux-2.4.20-pre6/include/asm-mips64/io.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/io.h	Thu Sep 12 20:01:49 2002
@@ -13,6 +13,7 @@
 #include <linux/config.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
+#include <asm/byteorder.h>
 
 #ifdef CONFIG_MIPS_ATLAS
 #include <asm/mips-boards/io.h>
@@ -35,11 +36,19 @@
 #endif
 
 #ifdef CONFIG_SIBYTE_SB1250
-#include <asm/sibyte/sb1250_io.h>
+#include <asm/sibyte/io.h>
 #endif
 
+#ifdef CONFIG_SGI_IP27
 extern unsigned long bus_to_baddr[256];
 
+#define bus_to_baddr(hwdev, addr) (bus_to_baddr[(hwdev)->bus->number] + (addr))
+#define baddr_to_bus(hwdev, addr) ((addr) - bus_to_baddr[(hwdev)->bus->number])
+#else
+#define bus_to_baddr(hwdev, addr) (addr)
+#define baddr_to_bus(hwdev, addr) (addr)
+#endif
+
 /*
  * Slowdown I/O port space accesses for antique hardware.
  */
@@ -52,7 +61,13 @@
 #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
 
 #define __ioswab8(x) (x)
+#ifdef CONFIG_SGI_IP22
+/* IP22 seems braindead enough to swap 16bits values in hardware, but
+   not 32bits.  Go figure... Can't tell without documentation. */
+#define __ioswab16(x) (x)
+#else
 #define __ioswab16(x) swab16(x)
+#endif
 #define __ioswab32(x) swab32(x)
 
 #else
@@ -77,7 +92,7 @@
  *     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. 
+ *     address.
  */
 static inline void * ioremap(unsigned long offset, unsigned long size)
 {
@@ -93,11 +108,11 @@
  *     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. 
+ *     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 
+ *     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
@@ -112,26 +127,23 @@
 {
 }
 
-/*
- * This assumes sane hardware.  The Origin is.
- */
-#define readb(addr)		(*(volatile unsigned char *) (addr))
-#define readw(addr)		(*(volatile unsigned short *) (addr))
-#define readl(addr)		(*(volatile unsigned int *) (addr))
+#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) = (b))
-#define writew(w,addr)		(*(volatile unsigned short *) (addr) = (w))
-#define writel(l,addr)		(*(volatile unsigned int *) (addr) = (l))
+#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 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))
 
@@ -171,7 +183,7 @@
  *
  *     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. 
+ *     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
@@ -253,7 +265,7 @@
 
 /*
  *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check 
+ *     @io_addr: mmio address to check
  *     @signature:  signature block
  *     @length: length of signature
  *
@@ -280,7 +292,7 @@
 
 /*
  *     isa_check_signature             -       find BIOS signatures
- *     @io_addr: mmio address to check 
+ *     @io_addr: mmio address to check
  *     @signature:  signature block
  *     @length: length of signature
  *
@@ -307,203 +319,130 @@
 	return retval;
 }
 
+#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)
 
-/*
- * Talk about misusing macros..
- */
+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;
 
-#define __OUT1(s) \
-static inline void __out##s(unsigned int value, unsigned long port) {
+	__val = *(volatile u8 *)(mips_io_port_base + port);
+	SLOW_DOWN_IO;
 
-#define __OUT2(m) \
-__asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
+	return __ioswab8(__val);
+}
+
+static inline unsigned short inw_p(unsigned long port)
+{
+	u16 __val;
 
-#define __OUT(m,s) \
-__OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); } \
-__OUT1(s##c) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); } \
-__OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); \
-	SLOW_DOWN_IO; } \
-__OUT1(s##c_p) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); \
-	SLOW_DOWN_IO; }
-
-#define __IN1(t,s) \
-static inline t __in##s(unsigned long 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) \
-__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return _v; } \
-__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return _v; } \
-__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return _v; } \
-__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return _v; }
-
-#define __INS1(s) \
-static inline void __ins##s(unsigned long 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" \
-	"dsubu\t%1, 1\n\t" \
-	"s" #m "\t$1,(%0)\n\t" \
-	"bnez\t%1, 1b\n\t" \
-	"daddiu\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));} \
-__INS1(s##c) __INS2(m) \
-	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), \
-	  "I" (i));}
-
-#define __OUTS1(s) \
-static inline void __outs##s(unsigned long 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" \
-	"dsubu\t%1, 1\n\t" \
-	"s" #m "\t$1, %4(%5)\n\t" \
-	"bnez\t%1, 1b\n\t" \
-	"daddiu\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));} \
-__OUTS1(s##c) __OUTS2(m) \
-	: "=r" (addr), "=r" (count) \
-	: "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), \
-	  "I" (i));}
-
-__IN(unsigned char,b,b)
-__IN(unsigned short,h,w)
-__IN(unsigned int,w,l)
-
-__OUT(b,b)
-__OUT(h,w)
-__OUT(w,l)
-
-__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)^(3)) && ((port)^(3)) < 32768) ? \
-	__outbc((val),(port)^(3)) : \
-	__outb((val),(port)^(3)))
-
-#define inb(port) \
-((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
-	__inbc((port)^(3)) : \
-	__inb((port)^(3)))
-
-#define outb_p(val,port) \
-((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
-	__outbc_p((val),(port)^(3)) : \
-	__outb_p((val),(port)^(3)))
-
-#define inb_p(port) \
-((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
-	__inbc_p((port)^(3)) : \
-	__inb_p((port)^(3)))
-
-#define outw(val,port) \
-((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \
-	__outwc((val),((port)^(2))) : \
-	__outw((val),((port)^(2))))
-
-#define inw(port) \
-((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \
-	__inwc((port)^(2)) : \
-	__inw((port)^(2)))
-
-#define outw_p(val,port) \
-((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \
-	__outwc_p((val),(port)^(2)) : \
-	__outw_p((val),(port)^(2)))
-
-#define inw_p(port) \
-((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \
-	__inwc_p((port)^(2)) : \
-	__inw_p((port)^(2)))
-
-#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)))
+	__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);
+}
+
+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
diff -urN linux-2.4.20-pre6/include/asm-mips64/ioctls.h linux-2.4.20-pre7/include/asm-mips64/ioctls.h
--- linux-2.4.20-pre6/include/asm-mips64/ioctls.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/ioctls.h	Thu Sep 12 20:01:49 2002
@@ -12,7 +12,7 @@
 #include <asm/ioctl.h>
 
 #define TCGETA		0x5401
-#define TCSETA		0x5402
+#define TCSETA		0x5402	/* Clashes with SNDCTL_TMR_START sound ioctl */
 #define TCSETAW		0x5403
 #define TCSETAF		0x5404
 
@@ -66,7 +66,7 @@
 #define TIOCGETP        0x7408
 #define TIOCSETP        0x7409
 #define TIOCSETN        0x740a			/* TIOCSETP wo flush */
- 
+
 /* #define TIOCSETA	_IOW('t', 20, struct termios) set termios struct */
 /* #define TIOCSETAW	_IOW('t', 21, struct termios) drain output, set */
 /* #define TIOCSETAF	_IOW('t', 22, struct termios) drn out, fls in, set */
diff -urN linux-2.4.20-pre6/include/asm-mips64/ip32/mace.h linux-2.4.20-pre7/include/asm-mips64/ip32/mace.h
--- linux-2.4.20-pre6/include/asm-mips64/ip32/mace.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/ip32/mace.h	Thu Sep 12 20:01:49 2002
@@ -50,8 +50,8 @@
 #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_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
 
 /*
diff -urN linux-2.4.20-pre6/include/asm-mips64/ipc.h linux-2.4.20-pre7/include/asm-mips64/ipc.h
--- linux-2.4.20-pre6/include/asm-mips64/ipc.h	Thu Feb 24 22:53:35 2000
+++ linux-2.4.20-pre7/include/asm-mips64/ipc.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_IPC_H
 #define _ASM_IPC_H
 
-/* 
+/*
  * These are used to wrap system calls on MIPS32.
  *
  * See arch/mips/kernel/sysmips.c for ugly details..
diff -urN linux-2.4.20-pre6/include/asm-mips64/ipcbuf.h linux-2.4.20-pre7/include/asm-mips64/ipcbuf.h
--- linux-2.4.20-pre6/include/asm-mips64/ipcbuf.h	Thu Feb 24 22:53:35 2000
+++ linux-2.4.20-pre7/include/asm-mips64/ipcbuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_IPCBUF_H
 #define _ASM_IPCBUF_H
 
-/* 
+/*
  * The ipc64_perm structure for alpha architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
@@ -18,7 +18,7 @@
 	__kernel_gid_t	gid;
 	__kernel_uid_t	cuid;
 	__kernel_gid_t	cgid;
-	__kernel_mode_t	mode; 
+	__kernel_mode_t	mode;
 	unsigned short	seq;
 	unsigned short	__pad1;
 	unsigned long	__unused1;
diff -urN linux-2.4.20-pre6/include/asm-mips64/irq.h linux-2.4.20-pre7/include/asm-mips64/irq.h
--- linux-2.4.20-pre6/include/asm-mips64/irq.h	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/include/asm-mips64/irq.h	Thu Sep 12 20:01:49 2002
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
- * Copyright (C) 1995, 96, 97, 98, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2001 Kanoj Sarcar
  */
@@ -42,13 +42,21 @@
 #define irq_cannonicalize(irq) (irq)	/* Sane hardware, sane code ... */
 #endif
 
-
 struct irqaction;
 extern int i8259_setup_irq(int irq, struct irqaction * new);
 extern void disable_irq(unsigned int);
+
+#ifdef CONFIG_NEW_IRQ
+extern void disable_irq_nosync(unsigned int);
+#else
+#define disable_irq_nosync	disable_irq
+#endif
+
 extern void enable_irq(unsigned int);
 
 /* Machine specific interrupt initialization  */
 extern void (*irq_setup)(void);
 
+extern void init_generic_irq(void);
+
 #endif /* _ASM_IRQ_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/linux_logo.h linux-2.4.20-pre7/include/asm-mips64/linux_logo.h
--- linux-2.4.20-pre6/include/asm-mips64/linux_logo.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/linux_logo.h	Thu Sep 12 20:01:49 2002
@@ -17,7 +17,7 @@
  * Serial_console ascii image can be any size,
  * but should contain %s to display the version
  */
- 
+
 #include <linux/init.h>
 #include <linux/version.h>
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/mc146818rtc.h linux-2.4.20-pre7/include/asm-mips64/mc146818rtc.h
--- linux-2.4.20-pre6/include/asm-mips64/mc146818rtc.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/mc146818rtc.h	Thu Sep 12 20:01:49 2002
@@ -12,9 +12,19 @@
 
 #include <asm/io.h>
 
-#ifndef RTC_PORT
-#define RTC_PORT(x)	(0x70 + (x))
-#endif
+
+/*
+ * This structure defines how to access various features of
+ * different machine types and how to access them.
+ */
+struct rtc_ops {
+	/* How to access the RTC register in a DS1287.  */
+	unsigned char (*rtc_read_data)(unsigned long addr);
+	void (*rtc_write_data)(unsigned char data, unsigned long addr);
+	int (*rtc_bcd_mode)(void);
+};
+
+extern struct rtc_ops *rtc_ops;
 
 /*
  * The yet supported machines all access the RTC index register via
@@ -29,19 +39,8 @@
 #define RTC_ALWAYS_BCD \
 rtc_ops->rtc_bcd_mode()
 
-/*
- * This structure defines how to access various features of
- * different machine types and how to access them.
- */
-struct rtc_ops {
-	/* How to access the RTC register in a DS1287.  */
-	unsigned char (*rtc_read_data)(unsigned long addr);
-	void (*rtc_write_data)(unsigned char data, unsigned long addr);
-	int (*rtc_bcd_mode)(void);
-};
 
-extern struct rtc_ops *rtc_ops;
-
-#define RTC_IRQ 8
+#define RTC_PORT(x)	(0x70 + (x))
+#define RTC_IRQ		8
 
 #endif /* _ASM_MC146818RTC_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/atlas.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/atlas.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/atlas.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/atlas.h	Thu Sep 12 20:01:49 2002
@@ -27,7 +27,7 @@
 
 #include <asm/addrspace.h>
 
-/* 
+/*
  * Atlas RTC-device indirect register access.
  */
 #define ATLAS_RTC_ADR_REG       (KSEG1ADDR(0x1f000800))
@@ -43,7 +43,7 @@
  * Atlas UART register base.
  */
 #define ATLAS_UART_REGS_BASE    (0x1f000900)
-#define ATLAS_BASE_BAUD ( 3686400 / 16 ) 
+#define ATLAS_BASE_BAUD ( 3686400 / 16 )
 
 /*
  * Atlas PSU standby register.
@@ -54,7 +54,7 @@
 /*
  * We make a universal assumption about the way the bootloader (YAMON)
  * have located the Philips SAA9730 chip.
- * This is not ideal, but is needed for setting up remote debugging as 
+ * This is not ideal, but is needed for setting up remote debugging as
  * soon as possible.
  */
 #define ATLAS_SAA9730_REG  (KSEG1ADDR(0x08800000))
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/atlasint.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/atlasint.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/atlasint.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/atlasint.h	Thu Sep 12 20:01:49 2002
@@ -29,8 +29,8 @@
 #define ATLASINT_UART      0
 #define ATLASINT_END      32
 
-/* 
- * Atlas registers are memory mapped on 64-bit aligned boundaries and 
+/*
+ * Atlas registers are memory mapped on 64-bit aligned boundaries and
  * only word access are allowed.
  */
 struct atlas_ictrl_regs {
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/bonito64.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/bonito64.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/bonito64.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/bonito64.h	Thu Sep 12 20:01:49 2002
@@ -11,7 +11,7 @@
  */
 
 /*
- * Bonito Register Map 
+ * Bonito Register Map
  * Copyright (c) 1999 Algorithmics Ltd
  *
  * Algorithmics gives permission for anyone to use and modify this file
@@ -20,7 +20,7 @@
  *
  * 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).
  */
@@ -75,7 +75,7 @@
 #define BONITO_PCICFG_BASE		0x1fe80000
 #define BONITO_PCICFG_SIZE		0x00080000
 #define BONITO_PCICFG_TOP		(BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
- 
+
 
 /* Bonito Register Bases */
 
@@ -184,7 +184,7 @@
 #define BONITO_PCIMAP_CFG		BONITO(BONITO_REGBASE + 0x18)
 
 /* 5. ICU & GPIO regs */
- 
+
 /* GPIO Regs - r/w */
 
 #define BONITO_GPIODATA_OFFSET          0x1c
@@ -231,7 +231,7 @@
 */
 
 /* 7. IDE DMA & Copier */
- 
+
 #define BONITO_CONFIGBASE		0x000
 #define BONITO_BONITOBASE		0x100
 #define BONITO_LDMABASE 		0x200
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/gt64120.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/gt64120.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/gt64120.h	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/gt64120.h	Thu Sep 12 20:01:49 2002
@@ -56,7 +56,7 @@
 #define GT_PCI1M1LD_OFS		    0x0b0
 #define GT_PCI1M1HD_OFS		    0x0b8
 
-#define GT_SCS0LD_OFS		    0x400	
+#define GT_SCS0LD_OFS		    0x400
 #define GT_SCS0HD_OFS		    0x404
 #define GT_SCS1LD_OFS		    0x408
 #define GT_SCS1HD_OFS		    0x40c
@@ -260,7 +260,7 @@
 #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
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/malta.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/malta.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/malta.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/malta.h	Thu Sep 12 20:01:49 2002
@@ -28,15 +28,15 @@
 #include <asm/addrspace.h>
 #include <asm/io.h>
 
-/* 
+/*
  * Malta I/O ports base address for the Galileo GT64120 and Algorithmics
- * Bonito system controllers. 
+ * 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.
  */
 #define MALTA_RTC_ADR_REG       0x70
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/msc01_pci.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/msc01_pci.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/msc01_pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/msc01_pci.h	Thu Sep 12 20:01:49 2002
@@ -94,7 +94,7 @@
 #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_DTO_BIT        0x00000100
 #define MSC01_PCI_INTCFG_MA_SHF         7
 #define MSC01_PCI_INTCFG_MA_MSK         0x00000080
 #define MSC01_PCI_INTCFG_MA_BIT         0x00000080
@@ -128,7 +128,7 @@
 #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_DTO_BIT       0x00000100
 #define MSC01_PCI_INTSTAT_MA_SHF        7
 #define MSC01_PCI_INTSTAT_MA_MSK        0x00000080
 #define MSC01_PCI_INTSTAT_MA_BIT        0x00000080
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/sead.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/sead.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/sead.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/sead.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,36 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * ########################################################################
+ *
+ * Defines of the SEAD board specific address-MAP, registers, etc.
+ *
+ */
+#ifndef _MIPS_SEAD_H
+#define _MIPS_SEAD_H
+
+#include <asm/addrspace.h>
+
+/*
+ * SEAD UART register base.
+ */
+#define SEAD_UART0_REGS_BASE    (0x1f000800)
+#define SEAD_BASE_BAUD ( 3686400 / 16 )
+
+#endif /* !(_MIPS_SEAD_H) */
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips-boards/seadint.h linux-2.4.20-pre7/include/asm-mips64/mips-boards/seadint.h
--- linux-2.4.20-pre6/include/asm-mips64/mips-boards/seadint.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/mips-boards/seadint.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,35 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * ########################################################################
+ *
+ * Defines for the SEAD interrupt controller.
+ *
+ */
+#ifndef _MIPS_SEADINT_H
+#define _MIPS_SEADINT_H
+
+/* Number of IRQ supported */
+#define SEADINT_UART0     0
+#define SEADINT_UART1     1
+#define SEADINT_END       2
+
+extern void seadint_init(void);
+
+#endif /* !(_MIPS_SEADINT_H) */
diff -urN linux-2.4.20-pre6/include/asm-mips64/mips64_cache.h linux-2.4.20-pre7/include/asm-mips64/mips64_cache.h
--- linux-2.4.20-pre6/include/asm-mips64/mips64_cache.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/mips64_cache.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,305 @@
+/*
+ * mips64_cache.h
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 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.
+ *
+ * ########################################################################
+ *
+ * Inline assembly cache operations.
+ *
+ * This file is the original r4cache.c file with modification that makes the
+ * cache handling more generic.
+ *
+ * FIXME: Handle split L2 caches.
+ *
+ */
+#ifndef _MIPS_MIPS64_CACHE_H
+#define _MIPS_MIPS64_CACHE_H
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+
+static inline void flush_icache_line_indexed(unsigned long addr)
+{
+	unsigned long waystep = icache_size/mips_cpu.icache.ways;
+	unsigned int way;
+
+	for (way = 0; way < mips_cpu.icache.ways; way++)
+	{
+		__asm__ __volatile__(
+			".set noreorder\n\t"
+			"cache %1, (%0)\n\t"
+			".set reorder"
+			:
+			: "r" (addr),
+			"i" (Index_Invalidate_I));
+
+		addr += waystep;
+	}
+}
+
+static inline void flush_dcache_line_indexed(unsigned long addr)
+{
+	unsigned long waystep = dcache_size/mips_cpu.dcache.ways;
+	unsigned int way;
+
+	for (way = 0; way < mips_cpu.dcache.ways; way++)
+	{
+		__asm__ __volatile__(
+			".set noreorder\n\t"
+			"cache %1, (%0)\n\t"
+			".set reorder"
+			:
+			: "r" (addr),
+			"i" (Index_Writeback_Inv_D));
+
+		addr += waystep;
+	}
+}
+
+static inline void flush_scache_line_indexed(unsigned long addr)
+{
+	unsigned long waystep = scache_size/mips_cpu.scache.ways;
+	unsigned int way;
+
+	for (way = 0; way < mips_cpu.scache.ways; way++)
+	{
+		__asm__ __volatile__(
+			".set noreorder\n\t"
+			"cache %1, (%0)\n\t"
+			".set reorder"
+			:
+			: "r" (addr),
+			"i" (Index_Writeback_Inv_SD));
+
+		addr += waystep;
+	}
+}
+
+static inline void flush_icache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\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"
+		"cache %1, (%0)\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"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_D));
+}
+
+static inline void invalidate_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Invalidate_SD));
+}
+
+static inline void flush_scache_line(unsigned long addr)
+{
+	__asm__ __volatile__(
+		".set noreorder\n\t"
+		"cache %1, (%0)\n\t"
+		".set reorder"
+		:
+		: "r" (addr),
+		  "i" (Hit_Writeback_Inv_SD));
+}
+
+/*
+ * 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"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		".dword\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"
+		"1:\tcache %1,(%0)\n"
+		"2:\t.set reorder\n\t"
+		".section\t__ex_table,\"a\"\n\t"
+		".dword\t1b,2b\n\t"
+		".previous"
+		:
+		: "r" (addr), "i" (Hit_Writeback_D));
+}
+
+#define cache_unroll(base,op)			\
+	__asm__ __volatile__("			\
+		.set noreorder;			\
+		cache %1, (%0);			\
+		.set reorder"			\
+		:				\
+		: "r" (base),			\
+		  "i" (op));
+
+
+static inline void blast_dcache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + dcache_size);
+
+	while(start < end) {
+		cache_unroll(start,Index_Writeback_Inv_D);
+		start += dc_lsize;
+	}
+}
+
+static inline void blast_dcache_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache_unroll(start,Hit_Writeback_Inv_D);
+		start += dc_lsize;
+	}
+}
+
+static inline void blast_dcache_page_indexed(unsigned long page)
+{
+	unsigned long start;
+	unsigned long end = (page + PAGE_SIZE);
+	unsigned long waystep = dcache_size/mips_cpu.dcache.ways;
+	unsigned int way;
+
+	for (way = 0; way < mips_cpu.dcache.ways; way++) {
+		start = page + way*waystep;
+		while(start < end) {
+			cache_unroll(start,Index_Writeback_Inv_D);
+			start += dc_lsize;
+		}
+	}
+}
+
+static inline void blast_icache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = (start + icache_size);
+
+	while(start < end) {
+		cache_unroll(start,Index_Invalidate_I);
+		start += ic_lsize;
+	}
+}
+
+static inline void blast_icache_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = (start + PAGE_SIZE);
+
+	while(start < end) {
+		cache_unroll(start,Hit_Invalidate_I);
+		start += ic_lsize;
+	}
+}
+
+static inline void blast_icache_page_indexed(unsigned long page)
+{
+	unsigned long start;
+	unsigned long end = (page + PAGE_SIZE);
+	unsigned long waystep = icache_size/mips_cpu.icache.ways;
+	unsigned int way;
+
+	for (way = 0; way < mips_cpu.icache.ways; way++) {
+		start = page + way*waystep;
+		while(start < end) {
+			cache_unroll(start,Index_Invalidate_I);
+			start += ic_lsize;
+		}
+	}
+}
+
+static inline void blast_scache(void)
+{
+	unsigned long start = KSEG0;
+	unsigned long end = KSEG0 + scache_size;
+
+	while(start < end) {
+		cache_unroll(start,Index_Writeback_Inv_SD);
+		start += sc_lsize;
+	}
+}
+
+static inline void blast_scache_page(unsigned long page)
+{
+	unsigned long start = page;
+	unsigned long end = page + PAGE_SIZE;
+
+	while(start < end) {
+		cache_unroll(start,Hit_Writeback_Inv_SD);
+		start += sc_lsize;
+	}
+}
+
+static inline void blast_scache_page_indexed(unsigned long page)
+{
+	unsigned long start;
+	unsigned long end = (page + PAGE_SIZE);
+	unsigned long waystep = scache_size/mips_cpu.scache.ways;
+	unsigned int way;
+
+	for (way = 0; way < mips_cpu.scache.ways; way++) {
+		start = page + way*waystep;
+		while(start < end) {
+			cache_unroll(start,Index_Writeback_Inv_SD);
+			start += sc_lsize;
+		}
+	}
+}
+
+#endif /* !(_MIPS_MIPS64_CACHE_H) */
+
+
diff -urN linux-2.4.20-pre6/include/asm-mips64/mipsregs.h linux-2.4.20-pre7/include/asm-mips64/mipsregs.h
--- linux-2.4.20-pre6/include/asm-mips64/mipsregs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/mipsregs.h	Thu Sep 12 20:01:49 2002
@@ -77,7 +77,7 @@
 #define CP0_IWATCH $18
 #define CP0_DWATCH $19
 
-/* 
+/*
  * Coprocessor 0 Set 1 register names
  */
 #define CP0_S1_DERRADDR0  $26
@@ -374,8 +374,10 @@
 #define CONF_CM_CACHABLE_CUW		6
 #define CONF_CM_CACHABLE_ACCELERATED	7
 #define CONF_CM_CMASK			7
+#define CONF_CU				(1 <<  3)
 #define CONF_DB				(1 <<  4)
 #define CONF_IB				(1 <<  5)
+#define CONF_SE				(1 << 12)
 #define CONF_SC				(1 << 17)
 #define CONF_AC                         (1 << 23)
 #define CONF_HALT                       (1 << 25)
@@ -504,8 +506,8 @@
         ".set\tmips0"                                           \
         : : "r" (value))
 
-/* 
- * This should be changed when we get a compiler that support the MIPS32 ISA. 
+/*
+ * This should be changed when we get a compiler that support the MIPS32 ISA.
  */
 #define read_mips32_cp0_config1()                               \
 ({ int __res;                                                   \
@@ -597,7 +599,7 @@
 {
 	unsigned long val;
 
-	__asm__ __volatile__(	
+	__asm__ __volatile__(
 		".set noreorder\n\t"
 		"dmfc0 %0, $2\n\t"
 		".set reorder"
diff -urN linux-2.4.20-pre6/include/asm-mips64/mmu_context.h linux-2.4.20-pre7/include/asm-mips64/mmu_context.h
--- linux-2.4.20-pre6/include/asm-mips64/mmu_context.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/mmu_context.h	Thu Sep 12 20:01:49 2002
@@ -19,7 +19,7 @@
 /*
  * 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 
+ * 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.
@@ -76,10 +76,10 @@
 #ifndef CONFIG_SMP
 	mm->context = 0;
 #else
-	mm->context = (unsigned long)kmalloc(smp_num_cpus * 
+	mm->context = (unsigned long)kmalloc(smp_num_cpus *
 				sizeof(unsigned long), GFP_KERNEL);
 	/*
- 	 * Init the "context" values so that a tlbpid allocation 
+ 	 * Init the "context" values so that a tlbpid allocation
 	 * happens on the first switch.
  	 */
 	if (mm->context == 0)
diff -urN linux-2.4.20-pre6/include/asm-mips64/msgbuf.h linux-2.4.20-pre7/include/asm-mips64/msgbuf.h
--- linux-2.4.20-pre6/include/asm-mips64/msgbuf.h	Thu Feb 24 22:53:35 2000
+++ linux-2.4.20-pre7/include/asm-mips64/msgbuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_MSGBUF_H
 #define _ASM_MSGBUF_H
 
-/* 
+/*
  * The msqid64_ds structure for alpha architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
@@ -13,15 +13,18 @@
 struct msqid64_ds {
 	struct ipc64_perm msg_perm;
 	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned long	__unused1;
 	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned long	__unused2;
 	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned long	__unused3;
 	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;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
 };
 
 #endif /* _ASM_MSGBUF_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/page.h linux-2.4.20-pre7/include/asm-mips64/page.h
--- linux-2.4.20-pre6/include/asm-mips64/page.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/page.h	Thu Sep 12 20:01:49 2002
@@ -32,6 +32,10 @@
 
 extern void (*_clear_page)(void * page);
 extern void (*_copy_page)(void * to, void * from);
+extern void mips64_clear_page_dc(unsigned long page);
+extern void mips64_clear_page_sc(unsigned long page);
+extern void mips64_copy_page_dc(unsigned long to, unsigned long from);
+extern void mips64_copy_page_sc(unsigned long to, unsigned long from);
 
 #define clear_page(page)	_clear_page(page)
 #define copy_page(to, from)	_copy_page(to, from)
@@ -51,6 +55,8 @@
 #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 __pmd(x)	((pmd_t) { (x) } )
 #define __pgd(x)	((pgd_t) { (x) } )
@@ -83,12 +89,15 @@
 #if defined(CONFIG_SGI_IP22) || defined(CONFIG_MIPS_ATLAS) || \
     defined(CONFIG_MIPS_MALTA)
 #define PAGE_OFFSET	0xffffffff80000000UL
+#define UNCAC_BASE	0xffffffffa0000000UL
 #endif
 #if defined(CONFIG_SGI_IP32)
 #define PAGE_OFFSET	0x9800000000000000UL
+#define UNCAC_BASE	0x9000000000000000UL
 #endif
 #if defined(CONFIG_SGI_IP27)
 #define PAGE_OFFSET	0xa800000000000000UL
+#define UNCAC_BASE	0x9000000000000000UL
 #endif
 #if defined(CONFIG_SIBYTE_SB1250)
 #define PAGE_OFFSET	0xa800000000000000UL
@@ -101,6 +110,9 @@
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 #endif
 
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
+#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
+
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/pci/bridge.h linux-2.4.20-pre7/include/asm-mips64/pci/bridge.h
--- linux-2.4.20-pre6/include/asm-mips64/pci/bridge.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/pci/bridge.h	Thu Sep 12 20:01:49 2002
@@ -612,7 +612,7 @@
 /* Bridge INT_DEV register bits definition */
 #define BRIDGE_INT_DEV_SHFT(n)		((n)*3)
 #define BRIDGE_INT_DEV_MASK(n)		(0x7 << BRIDGE_INT_DEV_SHFT(n))
-#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line))	
+#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line))
 
 /* Bridge interrupt(x) register bits definition */
 #define BRIDGE_INT_ADDR_HOST		0x0003FF00
diff -urN linux-2.4.20-pre6/include/asm-mips64/pci.h linux-2.4.20-pre7/include/asm-mips64/pci.h
--- linux-2.4.20-pre6/include/asm-mips64/pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/pci.h	Thu Sep 12 20:01:49 2002
@@ -7,8 +7,6 @@
 #define _ASM_PCI_H
 
 #include <linux/config.h>
-#include <linux/types.h>
-#include <asm/io.h>			/* for virt_to_bus()  */
 
 #ifdef __KERNEL__
 
@@ -40,13 +38,19 @@
  * MIPS has everything mapped statically.
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <asm/scatterlist.h>
 #include <linux/string.h>
 #include <asm/io.h>
 
+#if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476))
+#undef PCIBIOS_MIN_IO
+#undef PCIBIOS_MIN_MEM
+#define PCIBIOS_MIN_IO		0x0100000
+#define PCIBIOS_MIN_MEM		0x1000000
+#endif
+
 struct pci_dev;
 
 /*
@@ -79,38 +83,6 @@
 extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 
-
-#ifdef CONFIG_MAPPED_PCI_IO
-
-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 pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle,
-                                size_t size, int direction);
-extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
-                            int nelems, int direction);
-
-/* 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))
-
-#else /* CONFIG_MAPPED_PCI_IO  */
-
 /*
  * Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
@@ -121,13 +93,14 @@
 static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
 					size_t size, int direction)
 {
+	unsigned long addr = (unsigned long) ptr;
+
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-#ifdef CONFIG_NONCOHERENT_IO
-	dma_cache_wback_inv((unsigned long)ptr, size);
-#endif
-	return virt_to_bus(ptr);
+	dma_cache_wback_inv(addr, size);
+
+	return bus_to_baddr(hwdev->bus->number, __pa(ptr));
 }
 
 /*
@@ -144,16 +117,13 @@
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	/* Nothing to do */
-}
+	if (direction != PCI_DMA_TODEVICE) {
+		unsigned long addr;
 
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME)		(0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+		addr = baddr_to_bus(hwdev, dma_addr) + PAGE_OFFSET;
+		dma_cache_wback_inv(addr, size);
+	}
+}
 
 /*
  * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
@@ -169,11 +139,9 @@
 		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);
+	return bus_to_baddr(hwdev, page_to_phys(page) + offset);
 }
 
 static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
@@ -181,9 +149,23 @@
 {
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
-	/* Nothing to do */
+
+	if (direction != PCI_DMA_TODEVICE) {
+		unsigned long addr;
+
+		addr = baddr_to_bus(hwdev, dma_address) + PAGE_OFFSET;
+		dma_cache_wback_inv(addr, size);
+	}
 }
 
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+
 /*
  * Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
@@ -208,12 +190,19 @@
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	/* Make sure that gcc doesn't leave the empty loop body.  */
 	for (i = 0; i < nents; i++, sg++) {
-#ifdef CONFIG_NONCOHERENT_IO
-		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
-#endif
-		sg->dma_address = (char *)(__pa(sg->address));
+		if (sg->address && sg->page)
+			out_of_line_bug();
+		else if (!sg->address && !sg->page)
+			out_of_line_bug();
+
+		if (sg->address) {
+			dma_cache_wback_inv((unsigned long)sg->address,
+			                    sg->length);
+			sg->dma_address = bus_to_baddr(hwdev, __pa(sg->address));
+		} else
+			sg->dma_address = page_to_bus(sg->page) +
+			                  sg->offset;
 	}
 
 	return nents;
@@ -227,10 +216,24 @@
 static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 				int nents, int direction)
 {
+	int i;
+
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	/* Nothing to do */
+	if (direction == PCI_DMA_TODEVICE)
+		return;
+
+	for (i = 0; i < nents; i++, sg++) {
+		if (sg->address && sg->page)
+			out_of_line_bug();
+		else if (!sg->address && !sg->page)
+			out_of_line_bug();
+
+		if (!sg->address)
+			continue;
+		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
+	}
 }
 
 /*
@@ -247,11 +250,13 @@
 				       dma_addr_t dma_handle,
 				       size_t size, int direction)
 {
+	unsigned long addr;
+
 	if (direction == PCI_DMA_NONE)
 		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
+
+	addr = baddr_to_bus(hwdev, dma_handle) + PAGE_OFFSET;
+	dma_cache_wback_inv(addr, size);
 }
 
 /*
@@ -272,14 +277,19 @@
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	/*  Make sure that gcc doesn't leave the empty loop body.  */
+	/* Make sure that gcc doesn't leave the empty loop body.  */
 #ifdef CONFIG_NONCOHERENT_IO
 	for (i = 0; i < nelems; i++, sg++)
 		dma_cache_wback_inv((unsigned long)sg->address, sg->length);
 #endif
 }
-#endif /* CONFIG_MAPPED_PCI_IO  */
 
+/*
+ * 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.
+ */
 static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
 {
 	/*
@@ -287,45 +297,50 @@
 	 * so we can't guarantee allocations that must be
 	 * within a tighter range than GFP_DMA..
 	 */
+#ifdef CONFIG_ISA
 	if (mask < 0x00ffffff)
 		return 0;
+#endif
 
 	return 1;
 }
 
 /* This is always fine. */
-/* Well ...  this actually needs more thought ...  */
-#define pci_dac_dma_supported(pci_dev, mask)	(0)
+#define pci_dac_dma_supported(pci_dev, mask)	(1)
 
-#if 0
-static __inline__ dma64_addr_t
-pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+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);
+	dma64_addr_t addr = page_to_phys(page) + offset;
+
+	return (dma64_addr_t) bus_to_baddr(hwdev->bus->number, addr);
 }
 
-static __inline__ struct page *
-pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+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);
+	unsigned long poff = baddr_to_bus(hwdev, 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)
+static inline unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+	dma64_addr_t dma_addr)
 {
-	return (dma_addr & ~PAGE_MASK);
+	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)
+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. */
+	unsigned long addr;
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	addr = baddr_to_bus(hwdev->bus->number, dma_addr) + PAGE_OFFSET;
+	dma_cache_wback_inv(addr, len);
 }
-#endif
 
 /*
  * Return the index of the PCI controller for device.
@@ -339,7 +354,7 @@
  * returns, or alternatively stop on the first sg_dma_len(sg) which
  * is 0.
  */
-#define sg_dma_address(sg)	((unsigned long)((sg)->address))
+#define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
 #endif /* __KERNEL__ */
diff -urN linux-2.4.20-pre6/include/asm-mips64/pgalloc.h linux-2.4.20-pre7/include/asm-mips64/pgalloc.h
--- linux-2.4.20-pre6/include/asm-mips64/pgalloc.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/pgalloc.h	Thu Sep 12 20:01:49 2002
@@ -193,7 +193,7 @@
 #define pgd_free(pgd)           free_pgd_fast(pgd)
 #define pgd_alloc(mm)           get_pgd_fast()
 
-extern pte_t kptbl[(PAGE_SIZE<<KPTBL_PAGE_ORDER)/sizeof(pte_t)];
+extern pte_t kptbl[(PAGE_SIZE << PGD_ORDER)/sizeof(pte_t)];
 extern pmd_t kpmdtbl[PTRS_PER_PMD];
 
 extern int do_check_pgt_cache(int, int);
diff -urN linux-2.4.20-pre6/include/asm-mips64/pgtable-bits.h linux-2.4.20-pre7/include/asm-mips64/pgtable-bits.h
--- linux-2.4.20-pre6/include/asm-mips64/pgtable-bits.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/pgtable-bits.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,101 @@
+/*
+ * This file is subject to 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 - 2002 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
+ */
+#ifndef _ASM_PGTABLE_BITS_H
+#define _ASM_PGTABLE_BITS_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]00MC only         */
+#define _CACHE_CACHABLE_COW         (5<<9)  /* R4[04]00MC only         */
+#define _CACHE_CACHABLE_CUW         (6<<9)  /* R4[04]00MC 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 defined(CONFIG_NONCOHERENT_IO)
+#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_NONCOHERENT
+#else
+#define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
+#endif
+
+#define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 9)
+
+#endif /* _ASM_PGTABLE_BITS_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/pgtable.h linux-2.4.20-pre7/include/asm-mips64/pgtable.h
--- linux-2.4.20-pre6/include/asm-mips64/pgtable.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/pgtable.h	Thu Sep 12 20:01:49 2002
@@ -57,8 +57,8 @@
  * routines are not needed. Only the icache on a processor is not
  * coherent with the dcache of the _same_ processor, so we must flush
  * the icache so that it does not contain stale contents of physical
- * memory. No flushes are needed for dma coherency, since the o200s 
- * are io coherent. The only place where we might be overoptimizing 
+ * memory. No flushes are needed for dma coherency, since the o200s
+ * are io coherent. The only place where we might be overoptimizing
  * out icache flushes are from mprotect (when PROT_EXEC is added).
  */
 extern void andes_flush_icache_page(unsigned long);
@@ -77,10 +77,6 @@
 
 #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)
@@ -89,12 +85,6 @@
 #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 */
 
@@ -114,17 +104,17 @@
  * pair of 4K pages, giving 1024 (== PTRS_PER_PMD) 8 byte pointers to
  * page tables. Each page table is a single 4K page, giving 512 (==
  * PTRS_PER_PTE) 8 byte ptes. Each pgde is initialized to point to
- * invalid_pmd_table, each pmde is initialized to point to 
+ * invalid_pmd_table, each pmde is initialized to point to
  * invalid_pte_table, each pte is initialized to 0. When memory is low,
  * and a pmd table or a page table allocation fails, empty_bad_pmd_table
  * and empty_bad_page_table is returned back to higher layer code, so
- * that the failure is recognized later on. Linux does not seem to 
+ * that the failure is recognized later on. Linux does not seem to
  * handle these failures very well though. The empty_bad_page_table has
  * invalid pte entries in it, to force page faults.
- * Vmalloc handling: vmalloc uses swapper_pg_dir[0] (returned by 
- * pgd_offset_k), which is initalized to point to kpmdtbl. kpmdtbl is 
- * the only single page pmd in the system. kpmdtbl entries point into 
- * kptbl[] array. We reserve 1<<KPTBL_PAGE_ORDER pages to hold the
+ * Vmalloc handling: vmalloc uses swapper_pg_dir[0] (returned by
+ * pgd_offset_k), which is initalized to point to kpmdtbl. kpmdtbl is
+ * the only single page pmd in the system. kpmdtbl entries point into
+ * kptbl[] array. We reserve 1 << PGD_ORDER pages to hold the
  * vmalloc range translations, which the fault handler looks at.
  */
 
@@ -145,72 +135,19 @@
 #define PTRS_PER_PGD	1024
 #define PTRS_PER_PMD	1024
 #define PTRS_PER_PTE	512
-#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
+#define PGD_ORDER		1
+
+#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
 #define FIRST_USER_PGD_NR	0
 
-#define KPTBL_PAGE_ORDER  1
-#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))
-
-/* 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 */
-#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_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             */
-#define _CACHE_MASK                 (7<<9)
-
-#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 /* ! UNCACHED */
-#ifdef CONFIG_SGI_IP22
-#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT
-#else /* ! IP22 */
-#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
-#endif /* IP22 */
-#endif /* UNCACHED */
+#define VMALLOC_START		XKSEG
+#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+#define VMALLOC_END	\
+	(VMALLOC_START + ((1 << PGD_ORDER) * PTRS_PER_PTE * PAGE_SIZE))
+
+#include <asm/pgtable-bits.h>
 
-#define PAGE_NONE	__pgprot(_PAGE_PRESENT | PAGE_CACHABLE_DEFAULT)
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
 			PAGE_CACHABLE_DEFAULT)
 #define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_READ | \
@@ -220,7 +157,7 @@
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
 			_PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT)
 #define PAGE_USERIO     __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
-			_CACHE_UNCACHED)
+			PAGE_CACHABLE_DEFAULT)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
 			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
@@ -298,7 +235,7 @@
 
 static inline int pte_none(pte_t pte)
 {
-	return !pte_val(pte);
+	return !(pte_val(pte) & ~_PAGE_GLOBAL);
 }
 
 static inline int pte_present(pte_t pte)
@@ -314,15 +251,32 @@
 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
 }
 
 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));
 }
 
 /*
- * (pmds are folded into pgds so this doesnt get actually called,
+ * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
@@ -531,7 +485,7 @@
 	       ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
 }
 
-/* Find an entry in the third-level page table.. */ 
+/* Find an entry in the third-level page table.. */
 static inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
 {
 	return (pte_t *) (pmd_page(*dir)) +
@@ -583,6 +537,8 @@
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 
+#define io_remap_page_range remap_page_range
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_PGTABLE_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/posix_types.h linux-2.4.20-pre7/include/asm-mips64/posix_types.h
--- linux-2.4.20-pre6/include/asm-mips64/posix_types.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/posix_types.h	Thu Sep 12 20:01:49 2002
@@ -88,7 +88,7 @@
 
 #undef __FD_ISSET
 static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{ 
+{
 	unsigned long __tmp = __fd / __NFDBITS;
 	unsigned long __rem = __fd % __NFDBITS;
 	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
diff -urN linux-2.4.20-pre6/include/asm-mips64/processor.h linux-2.4.20-pre7/include/asm-mips64/processor.h
--- linux-2.4.20-pre6/include/asm-mips64/processor.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/processor.h	Thu Sep 12 20:01:49 2002
@@ -74,6 +74,7 @@
 extern void r3081_wait(void);
 extern void r39xx_wait(void);
 extern void r4k_wait(void);
+extern void au1k_wait(void);
 
 extern unsigned int vced_count, vcei_count;
 extern struct cpuinfo_mips cpu_data[];
@@ -86,12 +87,13 @@
 
 /*
  * Bus types (default is ISA, but people can check others with these..)
- * MCA_bus hardcoded to 0 for now.
- *
- * This needs to be extended since MIPS systems are being delivered with
- * numerous different types of bus systems.
  */
+#ifdef CONFIG_EISA
 extern int EISA_bus;
+#else
+#define EISA_bus (0)
+#endif
+
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/r4kcacheops.h linux-2.4.20-pre7/include/asm-mips64/r4kcacheops.h
--- linux-2.4.20-pre6/include/asm-mips64/r4kcacheops.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/r4kcacheops.h	Thu Sep 12 20:01:49 2002
@@ -35,6 +35,7 @@
 #define Hit_Writeback_Inv_D	0x15
 					/* 0x16 is unused */
 #define Hit_Writeback_Inv_SD	0x17
+#define R5K_Page_Invalidate_S	0x17
 #define Hit_Writeback_I		0x18
 #define Hit_Writeback_D		0x19
 					/* 0x1a is unused */
diff -urN linux-2.4.20-pre6/include/asm-mips64/riscos-syscall.h linux-2.4.20-pre7/include/asm-mips64/riscos-syscall.h
--- linux-2.4.20-pre6/include/asm-mips64/riscos-syscall.h	Tue Nov 28 21:42:04 2000
+++ linux-2.4.20-pre7/include/asm-mips64/riscos-syscall.h	Thu Sep 12 20:01:49 2002
@@ -220,7 +220,7 @@
 #define __NR_SVR4_reserved62		(__NR_SVR4 + 199)
 #define __NR_SVR4_reserved63		(__NR_SVR4 + 200)
 #define __NR_SVR4_aread			(__NR_SVR4 + 201)
-#define __NR_SVR4_awrite		(__NR_SVR4 + 202)	
+#define __NR_SVR4_awrite		(__NR_SVR4 + 202)
 #define __NR_SVR4_listio		(__NR_SVR4 + 203)
 #define __NR_SVR4_mips_acancel		(__NR_SVR4 + 204)
 #define __NR_SVR4_astatus		(__NR_SVR4 + 205)
diff -urN linux-2.4.20-pre6/include/asm-mips64/rrm.h linux-2.4.20-pre7/include/asm-mips64/rrm.h
--- linux-2.4.20-pre6/include/asm-mips64/rrm.h	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/include/asm-mips64/rrm.h	Thu Sep 12 20:01:49 2002
@@ -77,7 +77,7 @@
  * RRM_BINDPROCTORN:
  *
  * Return value when the X server calls it: 0
- */ 
+ */
 struct RRM_BindProcToRN {
 	int      rnid;
 };
diff -urN linux-2.4.20-pre6/include/asm-mips64/scatterlist.h linux-2.4.20-pre7/include/asm-mips64/scatterlist.h
--- linux-2.4.20-pre6/include/asm-mips64/scatterlist.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/scatterlist.h	Thu Sep 12 20:01:49 2002
@@ -1,21 +1,22 @@
-#ifndef __ASM_MIPS64_SCATTERLIST_H
-#define __ASM_MIPS64_SCATTERLIST_H
+#ifndef __ASM_SCATTERLIST_H
+#define __ASM_SCATTERLIST_H
 
 struct scatterlist {
-	char *  address;	/* Location data is to be transferred to */
-	struct page *page;
-	unsigned int length;
-
-	__u32 dma_address;
+	char * address;		/* Location data is to be transferred to,
+				   NULL for highmem page */
+	struct page * page;	/* Location for highmem page, if any */
+	unsigned int offset;
+	dma_addr_t dma_address;
+	unsigned long length;
 };
 
 struct mmu_sglist {
-        char *addr;
-        char *__dont_touch;
-        unsigned int len;
-        __u32 dma_addr;
+	char *addr;
+	char *__dont_touch;
+	unsigned long len;
+	dma_addr_t dvma_addr;
 };
 
-#define ISA_DMA_THRESHOLD (0x00ffffffUL)
+#define ISA_DMA_THRESHOLD (0x00ffffff)
 
-#endif /* __ASM_MIPS64_SCATTERLIST_H */
+#endif /* __ASM_SCATTERLIST_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/semaphore-helper.h linux-2.4.20-pre7/include/asm-mips64/semaphore-helper.h
--- linux-2.4.20-pre6/include/asm-mips64/semaphore-helper.h	Wed Jul  4 11:50:39 2001
+++ linux-2.4.20-pre7/include/asm-mips64/semaphore-helper.h	Thu Sep 12 20:01:49 2002
@@ -17,20 +17,18 @@
 	atomic_inc(&sem->waking);
 }
 
-static inline int
-waking_non_zero(struct semaphore *sem)
+static inline int waking_non_zero(struct semaphore *sem)
 {
 	int ret, tmp;
 
 	__asm__ __volatile__(
-	"1:\tll\t%1, %2\n\t"
+	"1:\tll\t%1, %2\t\t\t# waking_non_zero\n\t"
 	"blez\t%1, 2f\n\t"
 	"subu\t%0, %1, 1\n\t"
 	"sc\t%0, %2\n\t"
-	"beqz\t%0, 1b\n\t"
+	"beqz\t%0, 1b\n"
 	"2:"
-	".text"
-	: "=r" (ret), "=r" (tmp), "=m" (sem->waking)
+	: "=r" (ret), "=r" (tmp), "+m" (sem->waking)
 	: "0" (0));
 
 	return ret;
@@ -43,17 +41,17 @@
  *	-EINTR	interrupted
  *
  * We must undo the sem->count down_interruptible decrement
- * simultaneously and atomicly with the sem->waking adjustment,
+ * simultaneously and atomically with the sem->waking adjustment,
  * otherwise we can race with wake_one_more.
  *
- * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
+ * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words.
  *
  * Pseudocode:
  *
  * If(sem->waking > 0) {
  *	Decrement(sem->waking)
  *	Return(SUCCESS)
- * } else If(segnal_pending(tsk)) {
+ * } else If(signal_pending(tsk)) {
  *	Increment(sem->count)
  *	Return(-EINTR)
  * } else {
@@ -102,7 +100,7 @@
 	"b\t2f\n"
 	"1:\tbeqz\t%3, 2f\n\t"
 	"li\t%0, %4\n\t"
-	/* 
+	/*
 	 * It would be nice to assume that sem->count
 	 * is != -1, but we will guard against that case
 	 */
@@ -124,12 +122,11 @@
 }
 
 /*
- * waking_non_zero_trylock is unused.  we do everything in 
+ * waking_non_zero_trylock is unused.  we do everything in
  * down_trylock and let non-ll/sc hosts bounce around.
  */
 
-static inline int
-waking_non_zero_trylock(struct semaphore *sem)
+static inline int waking_non_zero_trylock(struct semaphore *sem)
 {
 #if WAITQUEUE_DEBUG
 	CHECK_MAGIC(sem->__magic);
diff -urN linux-2.4.20-pre6/include/asm-mips64/semaphore.h linux-2.4.20-pre7/include/asm-mips64/semaphore.h
--- linux-2.4.20-pre6/include/asm-mips64/semaphore.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/asm-mips64/semaphore.h	Thu Sep 12 20:01:49 2002
@@ -109,7 +109,7 @@
  * down_trylock returns 0 on success, 1 if we failed to get the lock.
  *
  * We must manipulate count and waking simultaneously and atomically.
- * Here, we this by using ll/sc on the pair of 32-bit words.
+ * Here, we do this by using lld/scd on the pair of 32-bit words.
  *
  * Pseudocode:
  *
diff -urN linux-2.4.20-pre6/include/asm-mips64/sembuf.h linux-2.4.20-pre7/include/asm-mips64/sembuf.h
--- linux-2.4.20-pre6/include/asm-mips64/sembuf.h	Thu Feb 24 22:53:35 2000
+++ linux-2.4.20-pre7/include/asm-mips64/sembuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_SEMBUF_H
 #define _ASM_SEMBUF_H
 
-/* 
+/*
  * The semid64_ds structure for the MIPS architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
diff -urN linux-2.4.20-pre6/include/asm-mips64/serial.h linux-2.4.20-pre7/include/asm-mips64/serial.h
--- linux-2.4.20-pre6/include/asm-mips64/serial.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/serial.h	Thu Sep 12 20:01:49 2002
@@ -20,6 +20,39 @@
  */
 #define BASE_BAUD (1843200 / 16)
 
+#ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
+
+/* 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 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 */
+
+#else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
+#define STD_SERIAL_PORT_DEFNS
+#endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
+
+#ifdef CONFIG_MIPS_SEAD
+#include <asm/mips-boards/sead.h>
+#include <asm/mips-boards/seadint.h>
+#define SEAD_SERIAL_PORT_DEFNS                  \
+	/* UART CLK   PORT IRQ     FLAGS        */                      \
+	{ 0, SEAD_BASE_BAUD, SEAD_UART0_REGS_BASE, SEADINT_UART0, STD_COM_FLAGS },     /* ttyS0 */
+#else
+#define SEAD_SERIAL_PORT_DEFNS
+#endif
+
+
 #ifdef CONFIG_SGI_IP27
 
 /*
@@ -39,8 +72,8 @@
  *
  * The first one to do a register_console becomes the preferred console
  * (if there is no kernel command line console= directive). /dev/console
- * (ie 5, 1) is then "aliased" into the device number returned by the 
- * "device" routine referred to in this console structure 
+ * (ie 5, 1) is then "aliased" into the device number returned by the
+ * "device" routine referred to in this console structure
  * (ip27prom_console_dev).
  *
  * Also look in ip27-pci.c:pci_fixuop_ioc3() for some comments on working
@@ -87,14 +120,16 @@
           flags: STD_COM_FLAGS,				\
           iomem_base: (u8*)MACE_BASE+MACEISA_SER2_BASE,	\
           iomem_reg_shift: 8,				\
-          io_type: SERIAL_IO_MEM},                      
+          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
+	IP32_SERIAL_PORT_DEFNS				\
+	SEAD_SERIAL_PORT_DEFNS				\
+	STD_SERIAL_PORT_DEFNS
 
 #define RS_TABLE_SIZE	64
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sgi/sgigio.h linux-2.4.20-pre7/include/asm-mips64/sgi/sgigio.h
--- linux-2.4.20-pre6/include/asm-mips64/sgi/sgigio.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/sgi/sgigio.h	Thu Sep 12 20:01:49 2002
@@ -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 -urN linux-2.4.20-pre6/include/asm-mips64/sgi/sgihpc.h linux-2.4.20-pre7/include/asm-mips64/sgi/sgihpc.h
--- linux-2.4.20-pre6/include/asm-mips64/sgi/sgihpc.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sgi/sgihpc.h	Thu Sep 12 20:01:49 2002
@@ -45,8 +45,8 @@
 	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 register has 
-				 * copletely different meaning for read 
+	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) */
@@ -235,7 +235,7 @@
 	hpcreg scsi1_ext[256];	/* SCSI channel 1 external regs */
 	char _unused4[0x07c00];	/* It'll only hurt a little... */
 
-	/* Ethernet external registers. Noone use them so we need some 
+	/* 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 */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sgi/sgint23.h linux-2.4.20-pre7/include/asm-mips64/sgi/sgint23.h
--- linux-2.4.20-pre6/include/asm-mips64/sgi/sgint23.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sgi/sgint23.h	Thu Sep 12 20:01:49 2002
@@ -16,17 +16,18 @@
 /* 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. HPC DMA and MC DMA interrups
- * are not supported this way. Driver is supposed to allocate HPC/MC 
+ * 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 ;-) 
+ * HAL2 driver). This will prevent many complications, trust me ;-)
  *	--ladis
  */
-#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' */
+#define SGINT_EISA	0	/* INDIGO 2 has 16 EISA irq levels */
+#define SGINT_CPU	16	/* MIPS CPU define 8 interrupt sources */
+#define SGINT_LOCAL0	24	/* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1	32	/* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2	40	/* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3	48	/* INDY has 8 local3 vectored irq levels */
+#define SGINT_END	56	/* End of 'spaces' */
 
 /*
  * Individual interrupt definitions for the INDY and Indigo2
@@ -42,7 +43,7 @@
 #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_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 */
@@ -87,7 +88,7 @@
 #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 */
@@ -107,7 +108,7 @@
 #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 */
@@ -199,7 +200,7 @@
 #endif
 #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 
+/* I am guesing there are only two unused registers here
  * but I could be wrong...			- andrewb
  */
 /*	u32 _unused[3]; */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sgialib.h linux-2.4.20-pre7/include/asm-mips64/sgialib.h
--- linux-2.4.20-pre6/include/asm-mips64/sgialib.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sgialib.h	Thu Sep 12 20:01:49 2002
@@ -6,7 +6,7 @@
  * SGI ARCS firmware interface library for the Linux kernel.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_SGIALIB_H
 #define _ASM_SGIALIB_H
@@ -24,12 +24,11 @@
 #define prom_argc(index) ((char *) (long) _prom_argc[(index)])
 
 extern int prom_flags;
-#define PROM_FLAG_ARCS  1
+#define PROM_FLAG_ARCS			1
+#define PROM_FLAG_USE_AS_CONSOLE	2
 
-/* Init the PROM library and it's internal data structures.  Called
- * at boot time from head.S before start_kernel is invoked.
- */
-extern int prom_init(int argc, char **argv, char **envp);
+/* Init the PROM library and it's internal data structures. */
+extern void prom_init(int argc, char **argv, char **envp, int *prom_vec);
 
 /* Simple char-by-char console I/O. */
 extern void prom_putchar(char c);
@@ -41,9 +40,9 @@
 /* Memory descriptor management. */
 #define PROM_MAX_PMEMBLOCKS    32
 struct prom_pmemblock {
-	LONG	base;		/* Within KSEG0 or XKPHYS. */
+	LONG base;		/* Within KSEG0 or XKPHYS. */
 	ULONG size;		/* In bytes. */
-        ULONG type;		/* free or prom memory */
+	ULONG type;		/* free or prom memory */
 };
 
 /* Get next memory descriptor after CURR, returns first descriptor
@@ -58,9 +57,6 @@
 extern void prom_meminit(void);
 extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
 
-/* Returns pointer to PROM physical memory block array. */
-extern struct prom_pmemblock *prom_getpblock_array(void);
-
 /* PROM device tree library routines. */
 #define PROM_NULL_COMPONENT ((pcomponent *) 0)
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sgiarcs.h linux-2.4.20-pre7/include/asm-mips64/sgiarcs.h
--- linux-2.4.20-pre6/include/asm-mips64/sgiarcs.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sgiarcs.h	Thu Sep 12 20:01:49 2002
@@ -13,6 +13,7 @@
 #define _ASM_SGIARCS_H
 
 #include <linux/config.h>
+#include <asm/types.h>
 #include <asm/arc/types.h>
 
 /* Various ARCS error codes. */
@@ -115,7 +116,7 @@
 	arc_prog,    /* A loaded program resides here */
 	arc_atmp,    /* temporary storage area */
 	arc_aperm,   /* permanent storage */
-	arc_fcontig, /* Contiguous and free */    
+	arc_fcontig, /* Contiguous and free */
 };
 
 union linux_memtypes {
@@ -164,11 +165,11 @@
 /* This prom has a bolixed design. */
 struct linux_bigint {
 #ifdef __MIPSEL__
-	unsigned long lo;
-	long hi;
+	u32 lo;
+	s32 hi;
 #else /* !(__MIPSEL__) */
-	long hi;
-	unsigned long lo;
+	s32 hi;
+	u32 lo;
 #endif
 };
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/shmbuf.h linux-2.4.20-pre7/include/asm-mips64/shmbuf.h
--- linux-2.4.20-pre6/include/asm-mips64/shmbuf.h	Thu Feb 24 22:53:35 2000
+++ linux-2.4.20-pre7/include/asm-mips64/shmbuf.h	Thu Sep 12 20:01:49 2002
@@ -1,7 +1,7 @@
 #ifndef _ASM_SHMBUF_H
 #define _ASM_SHMBUF_H
 
-/* 
+/*
  * The shmid64_ds structure for the MIPS architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
diff -urN linux-2.4.20-pre6/include/asm-mips64/shmiq.h linux-2.4.20-pre7/include/asm-mips64/shmiq.h
--- linux-2.4.20-pre6/include/asm-mips64/shmiq.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/shmiq.h	Thu Sep 12 20:01:49 2002
@@ -9,7 +9,7 @@
  *
  * This also contains some streams and idev bits.
  *
- * They may contain errors, please, refer to the source code of the Linux  
+ * They may contain errors, please, refer to the source code of the Linux
  * kernel for a definitive answer on what we have implemented
  *
  * Miguel.
@@ -97,7 +97,7 @@
  * head   is the user index into the events, user can modify this one.
  * tail   is managed by the kernel.
  * flags  is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED
- *        if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called 
+ *        if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called
  *        to notify the kernel.
  * events where the kernel sticks the events.
  */
@@ -192,14 +192,14 @@
         unsigned        hwMaxRes;
         int             hwMinVal;
         int             hwMaxVal;
-	
+
         unsigned char   possibleModes;
 #define IDEV_ABSOLUTE           0x0
 #define IDEV_RELATIVE           0x1
 #define IDEV_EITHER             0x2
-	
+
         unsigned char   mode;	/* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */
-	
+
         unsigned short  resolution;
         int             minVal;
         int             maxVal;
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/64bit.h linux-2.4.20-pre7/include/asm-mips64/sibyte/64bit.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/64bit.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/64bit.h	Thu Sep 12 20:01:49 2002
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2001 Broadcom Corporation
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ * Copyright (C) 2002 Ralf Baechle
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,20 +11,78 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
+#ifndef __ASM_SIBYTE_64BIT_H
+#define __ASM_SIBYTE_64BIT_H
 
+#include <linux/config.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 */
+#ifdef CONFIG_MIPS32
+
+#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;
+	unsigned long flags;
+	high = val >> 32;
+	low = val & 0xffffffff;
+	// save_flags(flags);
+	__save_and_cli(flags);
+	__asm__ __volatile__ (
+		".set push\n"
+		".set noreorder\n"
+		".set noat\n"
+		".set mips4\n"
+		"   dsll32 $2, %1, 0   \n"
+		"   dsll32 $1, %0, 0   \n"
+		"   dsrl32 $2, $2, 0   \n"
+		"   or     $1, $1, $2  \n"
+		"   sd $1, (%2)\n"
+		".set pop\n"
+		::"r" (high), "r" (low), "r" (addr)
+		:"$1", "$2");
+	__restore_flags(flags);
+}
+
+static inline u64 in64(unsigned long addr)
+{
+	u32 low, high;
+	unsigned long flags;
+	__save_and_cli(flags);
+	__asm__ __volatile__ (
+		".set push\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 /* CONFIG_MIPS32 */
+
+#ifdef CONFIG_MIPS64
 
+/*
+ * 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;
@@ -34,4 +93,20 @@
 	return *(volatile unsigned long *)addr;
 }
 
-#endif /* _ASM_SIBYTE_64BIT_H */
+#endif /* CONFIG_MIPS64 */
+
+/*
+ * Avoid interrupt mucking, just adjust the address for 4-byte access.
+ * Assume the addresses are 8-byte aligned.
+ */
+
+#ifdef __MIPSEB__
+#define __CSR_32_ADJUST 4
+#else
+#define __CSR_32_ADJUST 0
+#endif
+
+#define csr_out32(v,a) (*(u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v))
+#define csr_in32(a)    (*(u32 *)((unsigned long)(a) + __CSR_32_ADJUST))
+
+#endif /* __ASM_SIBYTE_64BIT_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/board.h linux-2.4.20-pre7/include/asm-mips64/sibyte/board.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/board.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/board.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,28 @@
+/*
+ * 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 _SIBYTE_BOARD_H
+#define _SIBYTE_BOARD_H
+
+#if defined(CONFIG_SIBYTE_PTSWARM) || defined(CONFIG_SIBYTE_SWARM)
+#include <asm/sibyte/swarm.h>
+#endif
+
+#endif
+
+
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/io.h linux-2.4.20-pre7/include/asm-mips64/sibyte/io.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/io.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/io.h	Thu Sep 12 20:01:49 2002
@@ -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 -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250.h	Thu Sep 12 20:01:49 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
@@ -19,9 +19,21 @@
 #ifndef _ASM_SIBYTE_SB1250_H
 #define _ASM_SIBYTE_SB1250_H
 
+#ifndef __ASSEMBLY__
+
+#include <asm/addrspace.h>
+
+/* For revision/pass information */
+#include <asm/sibyte/sb1250_scd.h>
+extern unsigned int sb1250_pass;
+
 extern void sb1250_time_init(void);
+extern unsigned long sb1250_gettimeoffset(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
+
+#define IO_SPACE_BASE KSEG1
 
 #endif
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_defs.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_defs.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_defs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_defs.h	Thu Sep 12 20:01:49 2002
@@ -1,21 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
-    *  Global constants and macros		File: sb1250_defs.h	
-    *  
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -25,38 +27,38 @@
     *
     *  You 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, 
+    *  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). 
+    *
+    *  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 
+    *  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 
+    *                  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 
+    *  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
@@ -74,7 +76,7 @@
 #define _SB1250_DEFS_H
 
 /*
- * Cast to 64-bit number.  Presumably the syntax is different in 
+ * 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.
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_dma.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_dma.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_dma.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_dma.h	Thu Sep 12 20:01:49 2002
@@ -1,24 +1,24 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -28,7 +28,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -43,9 +43,9 @@
     *  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_RX_CH_0
  * Registers: DMA_CONFIG0_MAC_x_TX_CH_0
  * Registers: DMA_CONFIG0_SER_x_RX
  * Registers: DMA_CONFIG0_SER_x_TX
@@ -83,7 +83,7 @@
 
 /*
  * Ethernet and Serial DMA Configuration Register 2 (Table 7-5)
- * Registers: DMA_CONFIG1_MAC_x_RX_CH_0 
+ * 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
@@ -131,11 +131,11 @@
 /*
  * DMA Descriptor Count Registers (Table 7-8)
  */
- 
+
 /* No bitfields */
 
 
-/* 
+/*
  * Current Descriptor Address Register (Table 7-11)
  */
 
@@ -202,13 +202,16 @@
 #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)
 
+/* Note: BADTCPCS is actually in DSCR_A */
+#define M_DMA_ETHRX_BADTCPCS	_SB_MAKEMASK1(0)	/* PASS2 */
+
 #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)
@@ -241,7 +244,7 @@
 
 #define M_DMA_ETHTX_SOP	    	    _SB_MAKEMASK1(63)
 
-/* 
+/*
  * Ethernet Transmit Options (Table 7-17)
  */
 
@@ -294,7 +297,7 @@
     *  Data Mover Registers
     ********************************************************************* */
 
-/* 
+/*
  * Data Mover Descriptor Base Address Register (Table 7-22)
  * Register: DM_DSCR_BASE_0
  * Register: DM_DSCR_BASE_1
@@ -302,10 +305,10 @@
  * Register: DM_DSCR_BASE_3
  */
 
-#define M_DM_DSCR_BASE_MBZ          _SB_MAKEMASK(3,0)
+#define M_DM_DSCR_BASE_MBZ          _SB_MAKEMASK(4,0)
 
 /*  Note: Just mask the base address and then OR it in. */
-#define S_DM_DSCR_BASE_ADDR         _SB_MAKE64(3)
+#define S_DM_DSCR_BASE_ADDR         _SB_MAKE64(4)
 #define M_DM_DSCR_BASE_ADDR         _SB_MAKEMASK(36,S_DM_DSCR_BASE_ADDR)
 
 #define S_DM_DSCR_BASE_RINGSZ       _SB_MAKE64(40)
@@ -331,7 +334,7 @@
 #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)
  */
 
@@ -364,7 +367,10 @@
 #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 M_DM_DSCRA_THROTTLE         _SB_MAKEMASK1(43) */ /* REMOVED PASS2 */
+
+#define M_DM_DSCRA_RD_BKOFF	    _SB_MAKEMASK1(52)		/* PASS2 */
+#define M_DM_DSCRA_WR_BKOFF	    _SB_MAKEMASK1(53)		/* PASS2 */
 
 #define S_DM_DSCRA_DIR_DEST         _SB_MAKE64(44)
 #define M_DM_DSCRA_DIR_DEST         _SB_MAKEMASK(2,S_DM_DSCRA_DIR_DEST)
@@ -398,7 +404,7 @@
 #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)
+#define M_DM_DSCRA_RESERVED2        _SB_MAKEMASK(10,54)
 
 /*
  * Data Mover Descriptor Doubleword "B"  (Table 7-25)
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_genbus.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_genbus.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_genbus.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_genbus.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
+    *
     *  Generic Bus Constants                     File: sb1250_genbus.h
-    *  
-    *  This module contains constants and macros useful for 
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -48,11 +48,13 @@
 #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_1L       2		/* PASS2 */
 #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_BURST_EN		_SB_MAKEMASK1(5)	/* PASS2 */
 #define M_IO_PARITY_ODD		_SB_MAKEMASK1(6)
 #define M_IO_NONMUX		_SB_MAKEMASK1(7)
 
@@ -92,11 +94,18 @@
 #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 M_IO_EARLY_CS	        _SB_MAKEMASK1(3)	/* PASS2 */
+
 #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_BURST_WIDTH           _SB_MAKE64(6)			/* PASS2 */
+#define M_IO_BURST_WIDTH           _SB_MAKEMASK(2,S_IO_BURST_WIDTH)	/* PASS2 */
+#define V_IO_BURST_WIDTH(x)        _SB_MAKEVALUE(x,S_IO_BURST_WIDTH)	/* PASS2 */
+#define G_IO_BURST_WIDTH(x)        _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH)	/* PASS2 */
+
 #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)
@@ -117,6 +126,8 @@
 #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 M_IO_RDY_SYNC	        _SB_MAKEMASK1(3)	/* PASS2 */
+
 #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)
@@ -155,6 +166,7 @@
 #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)
+#define M_IO_COH_ERR	        _SB_MAKEMASK1(14)	/* PASS2 */
 
 /*
  * PCMCIA configuration register (Table 12-6)
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_int.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_int.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_int.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_int.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -43,7 +43,7 @@
 
 /*
  * Interrupt sources (Table 4-8, UM 0.2)
- * 
+ *
  * First, the interrupt numbers.
  */
 
@@ -77,8 +77,8 @@
 #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_CYCLE_CP0_INT	    30		/* PASS2 */
+#define K_INT_CYCLE_CP1_INT	    31		/* PASS2 */
 #define K_INT_GPIO_0                32
 #define K_INT_GPIO_1                33
 #define K_INT_GPIO_2                34
@@ -108,9 +108,9 @@
 #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
+#define K_INT_MAC_0_CH1		    61		/* PASS2 */
+#define K_INT_MAC_1_CH1		    62		/* PASS2 */
+#define K_INT_MAC_2_CH1		    63		/* PASS2 */
 
 /*
  * Mask values for each interrupt
@@ -146,8 +146,8 @@
 #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_CYCLE_CP0_INT	    _SB_MAKEMASK1(K_INT_CYCLE_CP0_INT)	/* PASS2 */
+#define M_INT_CYCLE_CP1_INT	    _SB_MAKEMASK1(K_INT_CYCLE_CP1_INT)	/* PASS2 */
 #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)
@@ -177,9 +177,9 @@
 #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)
+#define M_INT_MAC_0_CH1		    _SB_MAKEMASK1(K_INT_MAC_0_CH1)	/* PASS2 */
+#define M_INT_MAC_1_CH1		    _SB_MAKEMASK1(K_INT_MAC_1_CH1)	/* PASS2 */
+#define M_INT_MAC_2_CH1		    _SB_MAKEMASK1(K_INT_MAC_2_CH1)	/* PASS2 */
 
 /*
  * Interrupt mappings
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_io.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_io.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_io.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_io.h	Wed Dec 31 16:00:00 1969
@@ -1,21 +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 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 -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_l2c.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_l2c.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_l2c.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_l2c.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -76,6 +76,14 @@
 #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_QUADRANT         15
+#define M_L2C_MGMT_QUADRANT         _SB_MAKEMASK(2,S_L2C_MGMT_QUADRANT)
+#define V_L2C_MGMT_QUADRANT(x)      _SB_MAKEVALUE(x,S_L2C_MGMT_QUADRANT)
+#define G_L2C_MGMT_QUADRANT(x)      _SB_GETVALUE(x,S_L2C_MGMT_QUADRANT,M_L2C_MGMT_QUADRANT)
+
+#define S_L2C_MGMT_HALF		    16
+#define M_L2C_MGMT_HALF	            _SB_MAKEMASK(1,S_L2C_MGMT_HALF)
+
 #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)
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_ldt.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_ldt.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_ldt.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_ldt.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  This module contains constants and macros to describe
+    *  the LDT interface on the SB1250.
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -70,6 +70,7 @@
 #define R_LDT_TYPE1_SRIRXNUM	0x0058
 #define R_LDT_TYPE1_ERRSTATUS   0x0068
 #define R_LDT_TYPE1_SRICTRL	0x006C
+#define R_LDT_TYPE1_ADDSTATUS	0x0070		/* PASS2 */
 #define R_LDT_TYPE1_TXBUFCNT	0x00C8
 #define R_LDT_TYPE1_EXPCRC	0x00DC
 #define R_LDT_TYPE1_RXCRC	0x00F0
@@ -152,13 +153,14 @@
 
 /*
  * LDT Status Register (Table 8-14).  Note that these constants
- * assume you've read the command and status register 
+ * 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_VGAEN		_SB_MAKEMASK1_32(3)	/* PASS2 */
 #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)
@@ -177,8 +179,8 @@
 #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 
+ * Bridge Control Register (Table 8-16).  Note that these
+ * constants assume you've read the register as a 32-bit
  * read (offset 0x3C)
  */
 
@@ -279,7 +281,10 @@
 #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 M_LDT_SRICMD_DISSTARVATIONCNT	_SB_MAKEMASK1_32(19) */ /* PASS1 */
+#define M_LDT_SRICMD_DISMULTTXVLD	_SB_MAKEMASK1_32(19)	/* PASS2 */
+#define M_LDT_SRICMD_EXPENDIAN		_SB_MAKEMASK1_32(26)	/* PASS2 */
+
 
 #define S_LDT_SRICMD_RXMARGIN		20
 #define M_LDT_SRICMD_RXMARGIN		_SB_MAKEMASK_32(5,S_LDT_SRICMD_RXMARGIN)
@@ -397,6 +402,14 @@
 #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)
 
+/*
+ * Additional Status Register (PASS2)
+ */
+
+#define S_LDT_ADDSTATUS_TGTDONE		0
+#define M_LDT_ADDSTATUS_TGTDONE		_SB_MAKEMASK_32(8,S_LDT_ADDSTATUS_TGTDONE)
+#define V_LDT_ADDSTATUS_TGTDONE(x)	_SB_MAKEVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE)
+#define G_LDT_ADDSTATUS_TGTDONE(x)	_SB_GETVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE,M_LDT_ADDSTATUS_TGTDONE)
 
 #endif
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_mac.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_mac.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_mac.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_mac.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -49,8 +49,6 @@
  */
 
 
-/* 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)
@@ -130,7 +128,7 @@
 #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 M_MAC_RX_CH_SEL_MSB	    _SB_MAKEMASK1(44)		/* PASS2 */
 
 #define S_MAC_BYPASS_IFG            _SB_MAKE64(46)
 #define M_MAC_BYPASS_IFG            _SB_MAKEMASK(8,S_MAC_BYPASS_IFG)
@@ -202,12 +200,14 @@
  */
 
 #define S_MAC_TX_WR_THRSH           _SB_MAKE64(0)
-#define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH)
+/* #define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH) */ /* PASS1 */
+#define M_MAC_TX_WR_THRSH           _SB_MAKEMASK(7,S_MAC_TX_WR_THRSH)	    /* PASS2 */
 #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 M_MAC_TX_RD_THRSH           _SB_MAKEMASK(6,S_MAC_TX_RD_THRSH) */ /* PASS1 */
+#define M_MAC_TX_RD_THRSH           _SB_MAKEMASK(7,S_MAC_TX_RD_THRSH)	    /* PASS2 */
 #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)
 
@@ -231,6 +231,11 @@
 #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)
 
+#define S_MAC_ENC_FC_THRSH           _SB_MAKE64(56)			/* PASS2 */
+#define M_MAC_ENC_FC_THRSH           _SB_MAKEMASK(6,S_MAC_ENC_FC_THRSH)	/* PASS2 */
+#define V_MAC_ENC_FC_THRSH(x)        _SB_MAKEVALUE(x,S_MAC_ENC_FC_THRSH) /* PASS2 */
+#define G_MAC_ENC_FC_THRSH(x)        _SB_GETVALUE(x,S_MAC_ENC_FC_THRSH,M_MAC_ENC_FC_THRSH) /* PASS2 */
+
 /*
  * MAC Frame Configuration Registers (Table 9-15)
  * Register: MAC_FRAME_CFG_0
@@ -280,20 +285,20 @@
 
 /*
  * These constants are used to configure the fields within the Frame
- * Configuration Register.  
+ * 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_RX_10             _SB_MAKE64(0)	/* See table 176, not used */
+#define K_MAC_IFG_RX_100            _SB_MAKE64(0)
+#define K_MAC_IFG_RX_1000           _SB_MAKE64(0)
 
 #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_IFG_THRSH_10          _SB_MAKE64(4)
+#define K_MAC_IFG_THRSH_100         _SB_MAKE64(4)
+#define K_MAC_IFG_THRSH_1000        _SB_MAKE64(0)
 
 #define K_MAC_SLOT_SIZE_10          _SB_MAKE64(0)
 #define K_MAC_SLOT_SIZE_100         _SB_MAKE64(0)
@@ -317,9 +322,11 @@
 
 #define K_MAC_MIN_FRAMESZ_DEFAULT   _SB_MAKE64(64)
 #define K_MAC_MAX_FRAMESZ_DEFAULT   _SB_MAKE64(1518)
+#define K_MAC_MAX_FRAMESZ_JUMBO     _SB_MAKE64(9216)
 
 #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)
+#define V_MAC_MAX_FRAMESZ_JUMBO     V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_JUMBO)
 
 /*
  * MAC VLAN Tag Registers (Table 9-16)
@@ -341,7 +348,7 @@
  * 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.
@@ -378,6 +385,7 @@
 #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 M_MAC_SPLIT_EN		    _SB_MAKEMASK1(47) 	/* interrupt mask only */ /* PASS2 */
 
 #define S_MAC_COUNTER_ADDR          _SB_MAKE64(47)
 #define M_MAC_COUNTER_ADDR          _SB_MAKEMASK(5,S_MAC_COUNTER_ADDR)
@@ -498,6 +506,7 @@
 #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 M_MAC_ALLMCAST_EN	_SB_MAKEMASK1(7)	/* PASS2 */
 
 #define S_MAC_IPHDR_OFFSET      _SB_MAKE64(8)
 #define M_MAC_IPHDR_OFFSET      _SB_MAKEMASK(8,S_MAC_IPHDR_OFFSET)
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_mc.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_mc.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_mc.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_mc.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
-    *  Memory Controller constants              File: sb1250_mc.h       
-    *  
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -166,7 +166,7 @@
 
 #define K_MC_REF_RATE_100MHz         0x62
 #define K_MC_REF_RATE_133MHz         0x81
-#define K_MC_REF_RATE_200MHz         0xC4 
+#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)
@@ -224,7 +224,7 @@
                                      V_MC_ADDR_DRIVE_DEFAULT | \
                                      V_MC_DATA_DRIVE_DEFAULT | \
                                      V_MC_CLOCK_DRIVE_DEFAULT | \
-                                     V_MC_REF_RATE_DEFAULT 
+                                     V_MC_REF_RATE_DEFAULT
 
 
 
@@ -298,69 +298,80 @@
  * SDRAM Timing Register  (Table 6-15)
  */
 
-#define M_MC_w2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(62)
+#define M_MC_w2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(60)
 #define M_MC_r2wIDLE_TWOCYCLES	  _SB_MAKEMASK1(61)
-#define M_MC_r2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(60)
+#define M_MC_r2rIDLE_TWOCYCLES	  _SB_MAKEMASK1(62)
 
 #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 G_MC_tFIFO(x)             _SB_GETVALUE(x,S_MC_tFIFO,M_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 G_MC_tRFC(x)              _SB_GETVALUE(x,S_MC_tRFC,M_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 G_MC_tCwCr(x)             _SB_GETVALUE(x,S_MC_tCwCr,M_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 G_MC_tRCr(x)              _SB_GETVALUE(x,S_MC_tRCr,M_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 G_MC_tRCw(x)              _SB_GETVALUE(x,S_MC_tRCw,M_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 G_MC_tRRD(x)              _SB_GETVALUE(x,S_MC_tRRD,M_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 G_MC_tRP(x)               _SB_GETVALUE(x,S_MC_tRP,M_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 G_MC_tCwD(x)              _SB_GETVALUE(x,S_MC_tCwD,M_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 M_MC_tCrDh		  M_tCrDh
 
 #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 G_MC_tCrD(x)              _SB_GETVALUE(x,S_MC_tCrD,M_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 G_MC_tRCD(x)              _SB_GETVALUE(x,S_MC_tRCD,M_MC_tRCD)
 #define K_MC_tRCD_DEFAULT         3
 #define V_MC_tRCD_DEFAULT         V_MC_tRCD(K_MC_tRCD_DEFAULT)
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_pci.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_pci.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_pci.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_pci.h	Wed Dec 31 16:00:00 1969
@@ -1,250 +0,0 @@
-/*  *********************************************************************
-    *  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 -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_prof.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_prof.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_prof.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_prof.h	Thu Sep 12 20:01:49 2002
@@ -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 -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_regs.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_regs.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_regs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_regs.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  01/02/2002
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -40,20 +40,20 @@
 
 /*  *********************************************************************
     *  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.  
-    *  
+    *  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
     ********************************************************************* */
 
@@ -97,7 +97,7 @@
 #define R_MC_TEST_ECC               0x0000000420
 #define R_MC_MCLK_CFG               0x0000000500
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * L2 Cache Control Registers
     ********************************************************************* */
 
@@ -107,7 +107,12 @@
 #define A_L2_MAKEDISABLE(x)         (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8))
 #define A_L2_MGMT_TAG_BASE          0x00D0000000
 
-/*  ********************************************************************* 
+#define A_L2_CACHE_DISABLE	   0x0010042000	/* PASS2 */
+#define A_L2_MAKECACHEDISABLE(x)   (A_L2_CACHE_DISABLE | (((x)&0x0F) << 8))	/* PASS2 */
+#define A_L2_MISC_CONFIG	   0x0010043000	/* PASS2 */
+
+
+/*  *********************************************************************
     * PCI Interface Registers
     ********************************************************************* */
 
@@ -115,7 +120,7 @@
 #define A_PCI_TYPE01_HEADER         0x00DE000800
 
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * Ethernet DMA and MACs
     ********************************************************************* */
 
@@ -162,7 +167,7 @@
             (R_MAC_DMA_CHANNEL_BASE(txrx,chan) +    \
             (reg))
 
-/* 
+/*
  * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE
  */
 
@@ -220,6 +225,7 @@
 #define R_MAC_INT_MASK                  0x00000410
 #define R_MAC_TXD_CTL                   0x00000420
 #define R_MAC_MDIO                      0x00000428
+#define R_MAC_STATUS1		        0x00000430	/* PASS2 */
 #define R_MAC_DEBUG_STATUS              0x00000448
 
 #define MAC_HASH_COUNT			8
@@ -227,7 +233,7 @@
 #define MAC_CHMAP_COUNT			4
 
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * DUART Registers
     ********************************************************************* */
 
@@ -250,6 +256,11 @@
 #define R_DUART_RX_HOLD             0x160
 #define R_DUART_TX_HOLD             0x170
 
+#define R_DUART_FULL_CTL	    0x140	/* PASS2 */
+#define R_DUART_OPCR_X		    0x180	/* PASS2 */
+#define R_DUART_AUXCTL_X	    0x190	/* PASS2 */
+
+
 /*
  * The IMR and ISR can't be addressed with A_DUART_CHANREG,
  * so use this macro instead.
@@ -310,7 +321,16 @@
 #define A_DUART_INPORT_CHNG_A       0x00100603D0
 #define A_DUART_INPORT_CHNG_B       0x00100603E0
 
-/*  ********************************************************************* 
+#define A_DUART_FULL_CTL_A	    0x0010060140	/* PASS2 */
+#define A_DUART_FULL_CTL_B	    0x0010060240	/* PASS2 */
+
+#define A_DUART_OPCR_A	  	    0x0010060180	/* PASS2 */
+#define A_DUART_OPCR_B	  	    0x0010060280	/* PASS2 */
+
+#define A_DUART_INPORT_CHNG_DEBUG   0x00100603F0	/* PASS2 */
+
+
+/*  *********************************************************************
     * Synchronous Serial Registers
     ********************************************************************* */
 
@@ -344,7 +364,7 @@
             (reg))
 
 
-/* 
+/*
  * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE
  */
 
@@ -404,7 +424,7 @@
 #define R_SER_RMON_RX_ERRORS        0x000001F0
 #define R_SER_RMON_RX_BADADDR       0x000001F8
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * Generic Bus Registers
     ********************************************************************* */
 
@@ -456,7 +476,7 @@
 #define R_IO_PCMCIA_CFG             0x0A60
 #define R_IO_PCMCIA_STATUS          0x0A70
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * GPIO Registers
     ********************************************************************* */
 
@@ -480,7 +500,7 @@
 #define R_GPIO_PIN_CLR              0x30
 #define R_GPIO_PIN_SET              0x38
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * SMBus Registers
     ********************************************************************* */
 
@@ -516,7 +536,7 @@
 #define R_SMB_CONTROL               0x0000000060
 #define R_SMB_PEC                   0x0000000070
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * Timer Registers
     ********************************************************************* */
 
@@ -575,16 +595,21 @@
 #define A_SCD_TIMER_CNT_3           0x0010020188
 #define A_SCD_TIMER_CFG_3           0x0010020198
 
-/*  ********************************************************************* 
+#define A_SCD_SCRATCH		   0x0010020C10		/* PASS2 */
+
+#define A_SCD_ZBBUS_CYCLE_COUNT	   0x0010030000		/* PASS2 */
+#define A_SCD_ZBBUS_CYCLE_CP0	   0x0010020C00		/* PASS2 */
+#define A_SCD_ZBBUS_CYCLE_CP1	   0x0010020C08		/* PASS2 */
+
+
+/*  *********************************************************************
     * 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
     ********************************************************************* */
 
@@ -602,9 +627,10 @@
 #define A_ADDR_TRAP_CFG_1           0x0010020448
 #define A_ADDR_TRAP_CFG_2           0x0010020450
 #define A_ADDR_TRAP_CFG_3           0x0010020458
+#define A_ADDR_TRAP_REG_DEBUG	    0x0010020460	/* PASS2 */
 
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * System Interrupt Mapper Registers
     ********************************************************************* */
 
@@ -632,7 +658,7 @@
 #define R_IMR_INTERRUPT_MAP_BASE        0x0200
 #define R_IMR_INTERRUPT_MAP_COUNT       64
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * System Performance Counter Registers
     ********************************************************************* */
 
@@ -642,11 +668,12 @@
 #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_SCD_BUS_ERR_STATUS_DEBUG  0x00100208D0	/* PASS2 */
 #define A_BUS_ERR_DATA_0            0x00100208A0
 #define A_BUS_ERR_DATA_1            0x00100208A8
 #define A_BUS_ERR_DATA_2            0x00100208B0
@@ -654,13 +681,13 @@
 #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
     ********************************************************************* */
 
@@ -683,7 +710,7 @@
 #define A_SCD_TRACE_SEQUENCE_6      0x0010020A90
 #define A_SCD_TRACE_SEQUENCE_7      0x0010020A98
 
-/*  ********************************************************************* 
+/*  *********************************************************************
     * System Generic DMA Registers
     ********************************************************************* */
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_scd.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_scd.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_scd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_scd.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -53,7 +53,8 @@
 
 #define K_SYS_REVISION_PASS1	    1
 #define K_SYS_REVISION_PASS2	    3
-#define K_SYS_REVISION_PASS3	    4 /* XXX Unknown */
+#define K_SYS_REVISION_PASS2_2	    16
+#define K_SYS_REVISION_PASS3	    32
 
 #define S_SYS_PART                  _SB_MAKE64(16)
 #define M_SYS_PART                  _SB_MAKEMASK(16,S_SYS_PART)
@@ -61,7 +62,7 @@
 #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 K_SYS_PART_SB1125           0x1125
 
 #define S_SYS_WID                   _SB_MAKE64(32)
 #define M_SYS_WID                   _SB_MAKEMASK(32,S_SYS_WID)
@@ -153,6 +154,9 @@
 #define M_SYS_MISR_MODE             _SB_MAKEMASK1(61)
 #define M_SYS_MISR_RESET            _SB_MAKEMASK1(62)
 
+#define M_SYS_SW_FLAG		    _SB_MAKEMASK1(63)	/* PASS2 */
+
+
 /*
  * Mailbox Registers (Table 4-3)
  * Registers: SCD_MBOX_CPU_x
@@ -346,6 +350,7 @@
 #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 M_SCD_TRACE_CFG_FORCECNT        _SB_MAKEMASK1(8)	/* PASS2 */
 
 #define S_SCD_TRACE_CFG_CUR_ADDR        10
 #define M_SCD_TRACE_CFG_CUR_ADDR        _SB_MAKEMASK(8,S_SCD_TRACE_CFG_CUR_ADDR)
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_smbus.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_smbus.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_smbus.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_smbus.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
+    *
     *  SMBUS Constants                          File: sb1250_smbus.h
-    *  
-    *  This module contains constants and macros useful for 
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *
+    *  SB1250 specification level:  01/02/2002
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -131,4 +131,44 @@
 #define M_SPEC_PEC                  _SB_MAKEMASK(8,S_SPEC_PEC)
 #define V_SPEC_MB(x)                _SB_MAKEVALUE(x,S_SPEC_PEC)
 
+
+/*  *********************************************************************
+    *  PASS2 Extensions to SMBus
+    ********************************************************************* */
+
+/* BEGIN PASS2 */
+
+#define S_SMB_CMDH                  8
+#define M_SMB_CMDH                  _SB_MAKEMASK(8,S_SMBH_CMD)
+#define V_SMB_CMDH(x)               _SB_MAKEVALUE(x,S_SMBH_CMD)
+
+#define M_SMB_EXTEND		    _SB_MAKEMASK1(14)
+
+#define M_SMB_DIR		    _SB_MAKEMASK1(13)
+
+#define S_SMB_DFMT                  8
+#define M_SMB_DFMT                  _SB_MAKEMASK(3,S_SMB_DFMT)
+#define V_SMB_DFMT(x)               _SB_MAKEVALUE(x,S_SMB_DFMT)
+#define G_SMB_DFMT(x)               _SB_GETVALUE(x,S_SMB_DFMT,M_SMB_DFMT)
+
+#define K_SMB_DFMT_1BYTE            0
+#define K_SMB_DFMT_2BYTE            1
+#define K_SMB_DFMT_3BYTE            2
+#define K_SMB_DFMT_4BYTE            3
+#define K_SMB_DFMT_NODATA           4
+#define K_SMB_DFMT_CMD4BYTE         5
+#define K_SMB_DFMT_CMD5BYTE         6
+#define K_SMB_DFMT_RESERVED         7
+
+#define V_SMB_DFMT_1BYTE	    V_SMB_DFMT(K_SMB_DFMT_1BYTE)
+#define V_SMB_DFMT_2BYTE	    V_SMB_DFMT(K_SMB_DFMT_2BYTE)
+#define V_SMB_DFMT_3BYTE	    V_SMB_DFMT(K_SMB_DFMT_3BYTE)
+#define V_SMB_DFMT_4BYTE	    V_SMB_DFMT(K_SMB_DFMT_4BYTE)
+#define V_SMB_DFMT_NODATA	    V_SMB_DFMT(K_SMB_DFMT_NODATA)
+#define V_SMB_DFMT_CMD4BYTE	    V_SMB_DFMT(K_SMB_DFMT_CMD4BYTE)
+#define V_SMB_DFMT_CMD5BYTE	    V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE)
+#define V_SMB_DFMT_RESERVED	    V_SMB_DFMT(K_SMB_DFMT_RESERVED)
+
+/* END PASS2 */
+
 #endif
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_syncser.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_syncser.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_syncser.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_syncser.h	Thu Sep 12 20:01:49 2002
@@ -6,18 +6,18 @@
     *  This module contains constants and macros useful for
     *  manipulating the SB1250's Synchronous Serial
     *
-    *  SB1250 specification level:  0.2
+    *  SB1250 specification level:  User's manual 1/02/02
     *
-    *  Author:  Mitch Lichtenberg (mitch@sibyte.com)
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_uart.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_uart.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250_uart.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250_uart.h	Thu Sep 12 20:01:49 2002
@@ -1,23 +1,23 @@
 /*  *********************************************************************
     *  SB1250 Board Support Package
-    *  
+    *
     *  UART Constants				File: sb1250_uart.h
-    *  
-    *  This module contains constants and macros useful for 
+    *
+    *  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)
-    *  
-    *********************************************************************  
+    *  SB1250 specification level:  User's manual 1/02/02
+    *
+    *  Author:  Mitch Lichtenberg (mpl@broadcom.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 
+    *
+    *  This program is free software; you can redistribute it and/or
+    *  modify it under the terms of the GNU 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,
@@ -27,7 +27,7 @@
     *
     *  You 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, 
+    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     *  MA 02111-1307 USA
     ********************************************************************* */
 
@@ -37,7 +37,7 @@
 
 #include "sb1250_defs.h"
 
-/* ********************************************************************** 
+/* **********************************************************************
    * DUART Registers
    ********************************************************************** */
 
@@ -144,7 +144,7 @@
 #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) 
+#define M_DUART_CMD_RESERVED             _SB_MAKEMASK1(7)
 
 /*
  * DUART Status Register (Table 10-6)
@@ -164,7 +164,7 @@
 
 /*
  * DUART Baud Rate Register (Table 10-7)
- * Register: DUART_CLK_SEL_A 
+ * Register: DUART_CLK_SEL_A
  * Register: DUART_CLK_SEL_B
  */
 
@@ -229,6 +229,9 @@
 #define M_DUART_IP3_CHNG_ENA        _SB_MAKEMASK1(3)
 #define M_DUART_ACR_RESERVED        _SB_MAKEMASK(4,4)
 
+#define M_DUART_CTS_CHNG_ENA        _SB_MAKEMASK1(0)
+#define M_DUART_CIN_CHNG_ENA        _SB_MAKEMASK1(2)
+
 /*
  * DUART Interrupt Status Register (Table 10-16)
  * Register: DUART_ISR
@@ -327,9 +330,20 @@
     (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
 
 /*
- * XXX To be added: Synchronous Serial definitions
+ * Full Interrupt Control Register (PASS2)
  */
 
+#define S_DUART_SIG_FULL           _SB_MAKE64(0)
+#define M_DUART_SIG_FULL           _SB_MAKEMASK(4,S_DUART_SIG_FULL)
+#define V_DUART_SIG_FULL(x)        _SB_MAKEVALUE(x,S_DUART_SIG_FULL)
+#define G_DUART_SIG_FULL(x)        _SB_GETVALUE(x,S_DUART_SIG_FULL,M_DUART_SIG_FULL)
+
+#define S_DUART_INT_TIME           _SB_MAKE64(4)
+#define M_DUART_INT_TIME           _SB_MAKEMASK(4,S_DUART_INT_TIME)
+#define V_DUART_INT_TIME(x)        _SB_MAKEVALUE(x,S_DUART_INT_TIME)
+#define G_DUART_INT_TIME(x)        _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME)
+
+
 /* ********************************************************************** */
 
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250regs.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250regs.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sb1250regs.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sb1250regs.h	Wed Dec 31 16:00:00 1969
@@ -1,176 +0,0 @@
-/*
- * 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 -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/sbmips.h linux-2.4.20-pre7/include/asm-mips64/sibyte/sbmips.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/sbmips.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/sbmips.h	Wed Dec 31 16:00:00 1969
@@ -1,654 +0,0 @@
-/*  *********************************************************************
-    *  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 -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/swarm.h linux-2.4.20-pre7/include/asm-mips64/sibyte/swarm.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/swarm.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/swarm.h	Thu Sep 12 20:01:49 2002
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001 Broadcom Corporation
+ * 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
@@ -10,19 +10,57 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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
 
-#ifndef _ASM_SIBYTE_SWARM_H
-#define _ASM_SIBYTE_SWARM_H
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_int.h>
 
 #define KERNEL_RESERVED_MEM 0x100000
-#define LED_BASE_ADDR 0x100a0020
 
+#define LEDS_CS         3
+
+#ifdef CONFIG_SIBYTE_SWARM
+
+/* Generic bus chip selects */
+#define IDE_CS          4
+#define PCMCIA_CS       6
+
+/* GPIOs */
+#define K_GPIO_GB_IDE   4
+#define K_INT_GB_IDE    (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#define K_GPIO_PC_READY 9
+#define K_INT_PC_READY  (K_INT_GPIO_0 + K_GPIO_PC_READY)
+
+#endif
+
+#ifdef __ASSEMBLY__
+#define setleds(t0,t1,c0,c1,c2,c3) \
+	li	t0, (LED_BASE_ADDR|0xa0000000); \
+	li	t1, c0; \
+	sb	t1, 0x18(t0); \
+	li	t1, c1; \
+	sb	t1, 0x10(t0); \
+	li	t1, c2; \
+	sb	t1, 0x08(t0); \
+	li	t1, c3; \
+	sb	t1, 0x00(t0)
+#else
 void swarm_setup(void);
-void setleds(char *str); 
+void setleds(char *str);
+
+#define AT_spin \
+	__asm__ __volatile__ (		\
+		".set noat\n"		\
+		"li $at, 0\n"		\
+		"1: beqz $at, 1b\n"	\
+		".set at\n"		\
+		)
+#endif
 
-#endif /* _ASM_SIBYTE_SWARM_H */
+#endif /* __ASM_SIBYTE_SWARM_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sibyte/swarm_ide.h linux-2.4.20-pre7/include/asm-mips64/sibyte/swarm_ide.h
--- linux-2.4.20-pre6/include/asm-mips64/sibyte/swarm_ide.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sibyte/swarm_ide.h	Thu Sep 12 20:01:49 2002
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You 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.
diff -urN linux-2.4.20-pre6/include/asm-mips64/sigcontext.h linux-2.4.20-pre7/include/asm-mips64/sigcontext.h
--- linux-2.4.20-pre6/include/asm-mips64/sigcontext.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sigcontext.h	Thu Sep 12 20:01:49 2002
@@ -23,7 +23,7 @@
 	unsigned int       sc_ownedfp;
 	unsigned int       sc_fpc_csr;
 	unsigned int       sc_fpc_eir;
-
+	unsigned int       sc_used_math;
 	unsigned int       sc_cause;
 	unsigned int       sc_badvaddr;
 };
diff -urN linux-2.4.20-pre6/include/asm-mips64/siginfo.h linux-2.4.20-pre7/include/asm-mips64/siginfo.h
--- linux-2.4.20-pre6/include/asm-mips64/siginfo.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/siginfo.h	Thu Sep 12 20:01:49 2002
@@ -18,11 +18,21 @@
 	void *sival_ptr;
 } sigval_t;
 
+#ifdef __KERNEL__
+
+typedef union sigval32 {
+	int sival_int;
+	s32 sival_ptr;
+} sigval_t32;
+
+#endif /* __KERNEL__ */
+
 /* This structure matches IRIX 32/n32 ABIs for binary compatibility but
    has Linux extensions.  */
 
 #define SI_MAX_SIZE	128
-#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 4)
+#define SI_PAD_SIZE32	((SI_MAX_SIZE/sizeof(int)) - 3)
 
 typedef struct siginfo {
 	int si_signo;
@@ -82,6 +92,68 @@
 	} _sifields;
 } siginfo_t;
 
+#ifdef __KERNEL__
+
+typedef struct siginfo32 {
+	int si_signo;
+	int si_code;
+	int si_errno;
+
+	union {
+		int _pad[SI_PAD_SIZE32];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t32 _pid;	/* sender's pid */
+			__kernel_uid_t32 _uid;	/* sender's uid */
+		} _kill;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t32 _pid;	/* which child */
+			__kernel_uid_t32 _uid;	/* sender's uid */
+			__kernel_clock_t32 _utime;
+			int _status;		/* exit code */
+			__kernel_clock_t32 _stime;
+		} _sigchld;
+
+		/* IRIX SIGCHLD */
+		struct {
+			__kernel_pid_t32 _pid;	/* which child */
+			__kernel_clock_t32 _utime;
+			int _status;		/* exit code */
+			__kernel_clock_t32 _stime;
+		} _irix_sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			s32 _addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t32 _pid;	/* sender's pid */
+			__kernel_uid_t32 _uid;	/* sender's uid */
+			sigval_t32 _sigval;
+		} _rt;
+
+	} _sifields;
+} siginfo_t32;
+
+#endif /* __KERNEL__ */
+
 /*
  * How these fields are to be accessed.
  */
@@ -204,8 +276,8 @@
 
 /*
  * sigevent definitions
- * 
- * It seems likely that SIGEV_THREAD will have to be handled from 
+ *
+ * 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.
diff -urN linux-2.4.20-pre6/include/asm-mips64/signal.h linux-2.4.20-pre7/include/asm-mips64/signal.h
--- linux-2.4.20-pre6/include/asm-mips64/signal.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/signal.h	Thu Sep 12 20:01:49 2002
@@ -89,7 +89,7 @@
 
 #define SA_RESTORER	0x04000000
 
-/* 
+/*
  * sigaltstack controls
  */
 #define SS_ONSTACK     1
diff -urN linux-2.4.20-pre6/include/asm-mips64/smp.h linux-2.4.20-pre7/include/asm-mips64/smp.h
--- linux-2.4.20-pre6/include/asm-mips64/smp.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/smp.h	Thu Sep 12 20:01:49 2002
@@ -42,8 +42,8 @@
 
 #define CPUMASK_CLRALL(p)	(p) = 0
 #define CPUMASK_SETB(p, bit)	(p) |= 1UL << (bit)
-#define CPUMASK_CLRB(p, bit)	(p) &= ~(1ULL << (bit))
-#define CPUMASK_TSTB(p, bit)	((p) & (1ULL << (bit)))
+#define CPUMASK_CLRB(p, bit)	(p) &= ~(1UL << (bit))
+#define CPUMASK_TSTB(p, bit)	((p) & (1UL << (bit)))
 
 #elif (NR_CPUS <= 128)
 
@@ -60,11 +60,11 @@
 
 #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))
+					(1UL << CPUMASK_SHFT(bit))
 #define CPUMASK_CLRB(p, bit)	(p)._bits[CPUMASK_INDEX(bit)] &= \
-					~(1ULL << CPUMASK_SHFT(bit))
+					~(1UL << CPUMASK_SHFT(bit))
 #define CPUMASK_TSTB(p, bit)	((p)._bits[CPUMASK_INDEX(bit)] & \
-					(1ULL << CPUMASK_SHFT(bit)))
+					(1UL << CPUMASK_SHFT(bit)))
 
 #else
 #error cpumask macros only defined for 128p kernels
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/gda.h linux-2.4.20-pre7/include/asm-mips64/sn/gda.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/gda.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/gda.h	Thu Sep 12 20:01:49 2002
@@ -9,7 +9,7 @@
  *
  * gda.h -- Contains the data structure for the global data area,
  * 	The GDA contains information communicated between the
- *	PROM, SYMMON, and the kernel. 
+ *	PROM, SYMMON, and the kernel.
  */
 #ifndef _ASM_SN_GDA_H
 #define _ASM_SN_GDA_H
@@ -23,9 +23,9 @@
  *
  * Version #	| Change
  * -------------+-------------------------------------------------------
- * 	1	| Initial SN0 version 
+ * 	1	| Initial SN0 version
  * 	2	| Prom sets g_partid field to the partition number. 0 IS
- *		| a valid partition #. 
+ *		| a valid partition #.
  */
 
 #define GDA_VERSION	2	/* Current GDA version # */
@@ -70,7 +70,7 @@
 #endif /* !__ASSEMBLY__ */
 /*
  * Define:	PART_GDA_VERSION
- * Purpose:	Define the minimum version of the GDA required, lower 
+ * Purpose:	Define the minimum version of the GDA required, lower
  *		revisions assume GDA is NOT set up, and read partition
  *		information from the board info.
  */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/intr.h linux-2.4.20-pre7/include/asm-mips64/sn/intr.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/intr.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/intr.h	Thu Sep 12 20:01:49 2002
@@ -31,7 +31,7 @@
 		REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (0x100|(_level)))
 
 /*
- * When clearing the interrupt, make sure this clear does make it 
+ * 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.
  */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/intr_public.h linux-2.4.20-pre7/include/asm-mips64/sn/intr_public.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/intr_public.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/intr_public.h	Thu Sep 12 20:01:49 2002
@@ -1,4 +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.
@@ -40,11 +40,11 @@
 	 * in the lowest-numbered masks (i.e., 0, 1, 2...).
 	 */
 	/* INT_PEND0: */
-	hubreg_t		intpend0_masks[N_INTPEND0_MASKS]; 
+	hubreg_t		intpend0_masks[N_INTPEND0_MASKS];
 	/* INT_PEND1: */
 	hubreg_t		intpend1_masks[N_INTPEND1_MASKS];
 	/* INT_PEND0: */
-	struct intr_vecblk_s	*dispatch0;	
+	struct intr_vecblk_s	*dispatch0;
 	/* INT_PEND1: */
 	struct intr_vecblk_s	*dispatch1;
 } hub_intmasks_t;
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/io.h linux-2.4.20-pre7/include/asm-mips64/sn/io.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/io.h	Wed Jul 12 15:15:10 2000
+++ linux-2.4.20-pre7/include/asm-mips64/sn/io.h	Thu Sep 12 20:01:49 2002
@@ -56,9 +56,9 @@
 #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 ? \
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/klconfig.h linux-2.4.20-pre7/include/asm-mips64/sn/klconfig.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/klconfig.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sn/klconfig.h	Thu Sep 12 20:01:49 2002
@@ -19,9 +19,9 @@
 
 /*
  * WARNING:
- *	Certain assembly language routines (notably xxxxx.s) in the IP27PROM 
- *	will depend on the format of the data structures in this file.  In 
- *      most cases, rearranging the fields can seriously break things.   
+ *	Certain assembly language routines (notably xxxxx.s) in the IP27PROM
+ *	will depend on the format of the data structures in this file.  In
+ *      most cases, rearranging the fields can seriously break things.
  *      Adding fields in the beginning or middle can also break things.
  *      Add fields if necessary, to the end of a struct in such a way
  *      that offsets of existing fields do not change.
@@ -76,11 +76,11 @@
 
 #define	MAX_MODULE_ID		255
 #define SIZE_PAD		4096 /* 4k padding for structures */
-/* 
- * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, 
- * 2 Midplanes assuming no pci card cages 
+/*
+ * 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) 
+#define MAX_SLOTS_PER_NODE	(1 + 2 + 6 + 2)
 
 /* XXX if each node is guranteed to have some memory */
 
@@ -117,7 +117,7 @@
 
 /* Structures to manage various data storage areas */
 /* The numbers must be contiguous since the array index i
-   is used in the code to allocate various areas. 
+   is used in the code to allocate various areas.
 */
 
 #define BOARD_STRUCT 		0
@@ -240,7 +240,7 @@
 
 /*
  * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD
- * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to 
+ * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to
  * the LOCAL/current NODE. REMOTE means it is attached to a different
  * node.(TBD - Need a way to treat ROUTER boards.)
  *
@@ -250,20 +250,20 @@
  * Figure below). The first byte of the rboard or lboard structure
  * is used to find out its type - no unions are used.
  * If it is a lboard, then the config info of this board will be found
- * on the local node. (LOCAL NODE BASE + offset value gives pointer to 
+ * on the local node. (LOCAL NODE BASE + offset value gives pointer to
  * the structure.
  * If it is a rboard, the local structure contains the node number
  * and the offset of the beginning of the LINKED LIST on the remote node.
  * The details of the hardware on a remote node can be built locally,
- * if required, by reading the LINKED LIST on the remote node and 
+ * if required, by reading the LINKED LIST on the remote node and
  * ignoring all the rboards on that node.
  *
- * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the 
- * First board info on the remote node. The remote node list is 
+ * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the
+ * First board info on the remote node. The remote node list is
  * traversed as the local list, using the REMOTE BASE ADDRESS and not
  * the local base address and ignoring all rboard values.
  *
- * 
+ *
  KLCONFIG
 
  +------------+      +------------+      +------------+      +------------+
@@ -290,7 +290,7 @@
                       +--------------------------------+
 
  *
- * Each BOARD consists of COMPONENTs and the BOARD structure has 
+ * Each BOARD consists of COMPONENTs and the BOARD structure has
  * pointers (offsets) to its COMPONENT structure.
  * The COMPONENT structure has version info, size and speed info, revision,
  * error info and the NIC info. This structure can accomodate any
@@ -298,19 +298,19 @@
  *
  * The ERRORINFO part of each BOARD has error information
  * that describes errors about the BOARD itself. It also has flags to
- * indicate the COMPONENT(s) on the board that have errors. The error 
- * information specific to the COMPONENT is present in the respective 
+ * indicate the COMPONENT(s) on the board that have errors. The error
+ * information specific to the COMPONENT is present in the respective
  * COMPONENT structure.
  *
- * The ERRORINFO structure is also treated like a COMPONENT, ie. the 
+ * The ERRORINFO structure is also treated like a COMPONENT, ie. the
  * BOARD has pointers(offset) to the ERRORINFO structure. The rboard
- * structure also has a pointer to the ERRORINFO structure. This is 
+ * structure also has a pointer to the ERRORINFO structure. This is
  * the place to store ERRORINFO about a REMOTE NODE, if the HUB on
- * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where 
+ * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where
  * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can
- * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info 
+ * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info
  * which is present on the REMOTE NODE.(TBD)
- * REMOTE ERRINFO can be stored on any of the nearest nodes 
+ * REMOTE ERRINFO can be stored on any of the nearest nodes
  * or on all the nearest nodes.(TBD)
  * Like BOARD structures, REMOTE ERRINFO structures can be built locally
  * using the rboard errinfo pointer.
@@ -319,9 +319,9 @@
  * interface routines are provided (TBD). The important thing to remember while
  * manipulating the structures, is that, the NODE number information should
  * be used. If the NODE is non-zero (remote) then each offset should
- * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. 
+ * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR.
  * This includes offsets for BOARDS, COMPONENTS and ERRORINFO.
- * 
+ *
  * Note that these structures do not provide much info about connectivity.
  * That info will be part of HWGRAPH, which is an extension of the cfg_t
  * data structure. (ref IP27prom/cfg.h) It has to be extended to include
@@ -342,11 +342,11 @@
  * IP27 BOARD classes
  */
 
-#define KLCLASS_MASK	0xf0   
+#define KLCLASS_MASK	0xf0
 #define KLCLASS_NONE	0x00
 #define KLCLASS_NODE	0x10             /* CPU, Memory and HUB board */
-#define KLCLASS_CPU	KLCLASS_NODE	
-#define KLCLASS_IO	0x20             /* BaseIO, 4 ch SCSI, ethernet, FDDI 
+#define KLCLASS_CPU	KLCLASS_NODE
+#define KLCLASS_IO	0x20             /* BaseIO, 4 ch SCSI, ethernet, FDDI
 					    and the non-graphics widget boards */
 #define KLCLASS_ROUTER	0x30             /* Router board */
 #define KLCLASS_MIDPLANE 0x40            /* We need to treat this as a board
@@ -420,7 +420,7 @@
  * out the board name from the NIC string. For values less than
  * 8 the name of the board needs to be hard coded in a few places.
  * When bringup started nic names had not standardized and so we
- * had to hard code. (For people interested in history.) 
+ * had to hard code. (For people interested in history.)
  */
 #define KLTYPE_XTHD   	(KLCLASS_PSEUDO_GFX | 0x9)
 
@@ -431,7 +431,7 @@
 				 (l->brd_flags & SECOND_NIC_PRESENT))
 #define IS_MIO_IOC3(l,n)	(IS_MIO_PRESENT(l) && (n > 2))
 
-/* 
+/*
  * board structures
  */
 
@@ -511,10 +511,10 @@
 
 
 /*
- * Generic info structure. This stores common info about a 
+ * Generic info structure. This stores common info about a
  * component.
  */
- 
+
 typedef struct klinfo_s {                  /* Generic info */
         unsigned char   struct_type;       /* type of this structure */
         unsigned char   struct_version;    /* version of this structure */
@@ -540,9 +540,9 @@
 /*
  * Component structures.
  * Following are the currently identified components:
- * 	CPU, HUB, MEM_BANK, 
+ * 	CPU, HUB, MEM_BANK,
  * 	XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE)
- * 	BRIDGE, IOC3, SuperIO, SCSI, FDDI 
+ * 	BRIDGE, IOC3, SuperIO, SCSI, FDDI
  * 	ROUTER
  * 	GRAPHICS
  */
@@ -614,9 +614,9 @@
 typedef u64 *router_t;
 
 /*
- * The port info in ip27_cfg area translates to a lboart_t in the 
+ * The port info in ip27_cfg area translates to a lboart_t in the
  * KLCONFIG area. But since KLCONFIG does not use pointers, lboart_t
- * is stored in terms of a nasid and a offset from start of KLCONFIG 
+ * is stored in terms of a nasid and a offset from start of KLCONFIG
  * area  on that nasid.
  */
 typedef struct klport_s {
@@ -692,7 +692,7 @@
 } klmod_serial_num_t;
 
 /* Macros needed to access serial number structure in lboard_t.
-   Hard coded values are necessary since we cannot treat 
+   Hard coded values are necessary since we cannot treat
    serial number struct as a component without losing compatibility
    between prom versions. */
 
@@ -789,7 +789,7 @@
 	klconf_off_t    gfx_mfg_nic;
 } klgfx_t;
 
-typedef struct klxthd_s {   
+typedef struct klxthd_s {
 	klinfo_t 	xthd_info ;
 	klconf_off_t	xthd_mfg_nic ;        /* MFG NIC string */
 } klxthd_t ;
@@ -815,9 +815,9 @@
 
 typedef struct klscsi_s {                          /* SCSI Controller */
 	klinfo_t 	scsi_info ;
-    	scsi_t       	scsi_specific   ; 
+    	scsi_t       	scsi_specific   ;
 	unsigned char 	scsi_numdevs ;
-	klconf_off_t	scsi_devinfo[MAX_SCSI_DEVS] ; 
+	klconf_off_t	scsi_devinfo[MAX_SCSI_DEVS] ;
 } klscsi_t ;
 
 typedef struct klscdev_s {                          /* SCSI device */
@@ -842,20 +842,20 @@
 
 typedef struct klmsdev_s {                          /* mouse device */
         klinfo_t        msdev_info ;
-        void 		*msdev_cfg ; 
+        void 		*msdev_cfg ;
 } klmsdev_t ;
 
 #define MAX_FDDI_DEVS 10 /* XXX Is this true */
 
 typedef struct klfddi_s {                          /* FDDI */
 	klinfo_t 	fddi_info ;
-    	fddi_t        	fddi_specific ;       
+    	fddi_t        	fddi_specific ;
 	klconf_off_t	fddi_devinfo[MAX_FDDI_DEVS] ;
 } klfddi_t ;
 
 typedef struct klmio_s {                          /* MIO */
 	klinfo_t 	mio_info ;
-    	mio_t       	mio_specific   ; 
+    	mio_t       	mio_specific   ;
 } klmio_t ;
 
 
@@ -890,17 +890,17 @@
 
 /*
  * TBD - Can the ARCS and device driver related info also be included in the
- * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t 
+ * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t
  * structure, viz private to the IO4prom.
  */
 
-/* 
- * TBD - Allocation issues. 
+/*
+ * TBD - Allocation issues.
  *
- * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component, 
- * errinfo and allocate from them, or have a single heap and allocate all 
+ * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component,
+ * errinfo and allocate from them, or have a single heap and allocate all
  * structures from it. Debug is easier in the former method since we can
- * dump all similar structs in one command, but there will be lots of holes, 
+ * dump all similar structs in one command, but there will be lots of holes,
  * in memory and max limits are needed for number of structures.
  * Another way to make it organized, is to have a union of all components
  * and allocate a aligned chunk of memory greater than the biggest
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/kldir.h linux-2.4.20-pre7/include/asm-mips64/sn/kldir.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/kldir.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/kldir.h	Thu Sep 12 20:01:49 2002
@@ -199,7 +199,7 @@
 #define IP27_NMI_KREGS_OFFSET		0x11400
 #define IP27_NMI_KREGS_CPU_SIZE		0x200
 /*
- * save area of kernel nmi regs in eframe format 
+ * save area of kernel nmi regs in eframe format
  */
 #define IP27_NMI_EFRAME_OFFSET		0x11800
 #define IP27_NMI_EFRAME_SIZE		0x200
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/mapped_kernel.h linux-2.4.20-pre7/include/asm-mips64/sn/mapped_kernel.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/mapped_kernel.h	Sun Feb  4 21:48:46 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sn/mapped_kernel.h	Thu Sep 12 20:01:49 2002
@@ -6,18 +6,18 @@
 #define __ASM_SN_MAPPED_KERNEL_H
 
 /*
- * Note on how mapped kernels work: the text and data section is 
- * compiled at cksseg segment (LOADADDR = 0xc001c000), and the 
- * init/setup/data section gets a 16M virtual address bump in the 
- * ld.script file (so that tlblo0 and tlblo1 maps the sections). 
- * The vmlinux.64 section addresses are put in the xkseg range 
- * using the change-addresses makefile option. Use elfdump -of 
- * on IRIX to see where the sections go. The Origin loader loads 
- * the two sections contiguously in physical memory. The loader 
- * sets the entry point into kernel_entry using a xkphys address, 
- * but instead of using 0xa800000001160000, it uses the address 
- * 0xa800000000160000, which is where it physically loaded that 
- * code. So no jumps can be done before we have switched to using 
+ * Note on how mapped kernels work: the text and data section is
+ * compiled at cksseg segment (LOADADDR = 0xc001c000), and the
+ * init/setup/data section gets a 16M virtual address bump in the
+ * ld.script file (so that tlblo0 and tlblo1 maps the sections).
+ * The vmlinux.64 section addresses are put in the xkseg range
+ * using the change-addresses makefile option. Use elfdump -of
+ * on IRIX to see where the sections go. The Origin loader loads
+ * the two sections contiguously in physical memory. The loader
+ * sets the entry point into kernel_entry using a xkphys address,
+ * but instead of using 0xa800000001160000, it uses the address
+ * 0xa800000000160000, which is where it physically loaded that
+ * code. So no jumps can be done before we have switched to using
  * cksseg addresses.
  */
 #include <linux/config.h>
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/nmi.h linux-2.4.20-pre7/include/asm-mips64/sn/nmi.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/nmi.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/nmi.h	Thu Sep 12 20:01:49 2002
@@ -1,4 +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.
@@ -8,7 +8,7 @@
 #ifndef __ASM_SN_NMI_H
 #define __ASM_SN_NMI_H
 
-#ident "$Revision: 1.2.4.1 $"
+#ident "$Revision: 1.2.4.2 $"
 
 #include <asm/sn/addrs.h>
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/sn0/arch.h linux-2.4.20-pre7/include/asm-mips64/sn/sn0/arch.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/sn0/arch.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sn/sn0/arch.h	Thu Sep 12 20:01:49 2002
@@ -49,7 +49,7 @@
 #define MAX_PREMIUM_REGIONS     MAX_REGIONS
 
 /*
- * MAX_PARITIONS refers to the maximum number of logically defined 
+ * MAX_PARITIONS refers to the maximum number of logically defined
  * partitions the system can support.
  */
 #define MAX_PARTITIONS		MAX_REGIONS
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/sn0/hubio.h linux-2.4.20-pre7/include/asm-mips64/sn/sn0/hubio.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/sn0/hubio.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/sn0/hubio.h	Thu Sep 12 20:01:49 2002
@@ -18,7 +18,7 @@
  * In general, the longer software name should be used when available.
  */
 
-/* 
+/*
  * Slightly friendlier names for some common registers.
  * The hardware definitions follow.
  */
@@ -26,7 +26,7 @@
 #define IIO_WIDGET_STAT		IIO_WSTAT    /* Widget status register */
 #define IIO_WIDGET_CTRL		IIO_WCR	     /* Widget control register */
 #define IIO_WIDGET_TOUT		IIO_WRTO     /* Widget request timeout */
-#define IIO_WIDGET_FLUSH	IIO_WTFR     /* Widget target flush */ 
+#define IIO_WIDGET_FLUSH	IIO_WTFR     /* Widget target flush */
 #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 */
@@ -67,8 +67,8 @@
 
 /*
  * The following definitions use the names defined in the IO interface
- * document for ease of reference.  When possible, software should 
- * generally use the the longer but clearer names defined above.
+ * document for ease of reference.  When possible, software should
+ * generally use the longer but clearer names defined above.
  */
 
 #define IIO_BASE	0x400000
@@ -198,7 +198,7 @@
 } hubii_wcr_t;
 
 #define	iwcr_dir_con	wcr_fields_s.wcr_dir_con
-	    
+
 typedef union hubii_wstat_u {
 	u64      reg_value;
 	struct {
@@ -215,13 +215,13 @@
 	} wstat_fields_s;
 } hubii_wstat_t;
 
-		
+
 typedef union hubii_ilcsr_u {
 	u64	icsr_reg_value;
 	struct {
 		u64 	icsr_rsvd: 	22,	/* unused */
                    	icsr_max_burst:	10,	/* max burst */
-                        icsr_rsvd4:	 6,	/* reserved */	          
+                        icsr_rsvd4:	 6,	/* reserved */
                    	icsr_max_retry:	10,	/* max retry */
                         icsr_rsvd3:	 2,	/* reserved */
                         icsr_lnk_stat:	 2,	/* link status */
@@ -285,7 +285,7 @@
 
 typedef union io_perf_cnt {
 	u64	perf_cnt;
-	struct { 
+	struct {
 		u64	perf_rsvd1 : 32,
   			        perf_rsvd2 : 12,
   			        perf_cnt   : 20;
@@ -299,9 +299,9 @@
 
 #define IIO_LLP_CB_MAX	0xffff
 #define IIO_LLP_SN_MAX	0xffff
-	    
+
 /* IO PRB Entries */
-#define	IIO_NUM_IPRBS	(9)		
+#define	IIO_NUM_IPRBS	(9)
 #define IIO_IOPRB_0	0x400198	/* PRB entry 0 */
 #define IIO_IOPRB_8	0x4001a0	/* PRB entry 8 */
 #define IIO_IOPRB_9	0x4001a8	/* PRB entry 9 */
@@ -320,7 +320,7 @@
 #define IIO_IECLR	0x4001f8	/* IO error clear */
 #define IIO_IBCN        0x400200        /* IO BTE CRB count */
 
-/* 
+/*
  * IIO_IMEM Register fields.
  */
 #define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
@@ -366,7 +366,7 @@
 #define IIO_ICMR_CLR_RPPD	(1UL << 13)
 #define IIO_ICMR_CLR_RQPD	(1UL << 12)
 
-/* 
+/*
  * IIO PIO Deallocation register field masks : (IIO_IPDR)
  */
 #define	IIO_IPDR_PND	(1 << 4)
@@ -377,7 +377,7 @@
 #define	IIO_ICDR_PND	(1 << 4)
 
 /*
- * IIO CRB control register Fields: IIO_ICCR 
+ * IIO CRB control register Fields: IIO_ICCR
  */
 #define	IIO_ICCR_PENDING	(0x10000)
 #define	IIO_ICCR_CMD_MASK	(0xFF)
@@ -385,7 +385,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 
+#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory
 					 * via a WB
 					 */
 #define	IIO_ICCR_CMD_FLUSH	(0x800)
@@ -423,15 +423,15 @@
  *
  * 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. 
- * 
+ * 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. 
+ * fields in CRB.
  *
- * Updating CRB requires all activities in Hub IIO to be quiesced. 
+ * 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 hub IIO's status.
- * Quiescing implies  no dmas no PIOs 
+ * 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.
@@ -465,7 +465,7 @@
    NI_STATUS_REV_ID register. */
 typedef union h1_icrba_u {
 	u64	reg_value;
-	
+
 	struct {
 		u64 	resvd: 	6,
 			unused:	1,	/* Unused but RW!!	*/
@@ -505,11 +505,11 @@
 #define	IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
 
 /*
- * values for "ecode" field 
+ * 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 
+#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 */
@@ -537,15 +537,15 @@
 				 * 3: Reserved.
 				 */
 		srcnode: 9,	/* Source Node ID		*/
-		srcinit: 2,	/* Source Initiator: 
+		srcinit: 2,	/* Source Initiator:
 				 * See below for field values.
 				 */
 		useold:	1,	/* Use OLD command for processing */
 		imsgtype: 2,	/* Incoming message type
-				 * see below for field values 
+				 * see below for field values
 				 */
 		imsg: 	8,	/* Incoming message 	*/
-		initator: 3,	/* Initiator of original request 
+		initator: 3,	/* Initiator of original request
 				 * See below for field values.
 				 */
 		reqtype: 5,	/* Identifies type of request
@@ -579,18 +579,18 @@
 					 * 3: Reserved.
 					 */
 			srcnode: 9,	/* Source Node ID		*/
-			srcinit: 2,	/* Source Initiator: 
+			srcinit: 2,	/* Source Initiator:
 					 * See below for field values.
 					 */
 			useold:	1,	/* Use OLD command for processing */
 			imsgtype: 2,	/* Incoming message type
-					 * see below for field values 
+					 * see below for field values
 					 */
 			imsg: 	8,	/* Incoming message 	*/
-			initator: 3,	/* Initiator of original request 
+			initator: 3,	/* Initiator of original request
 					 * See below for field values.
 					 */
-			rsvd2: 	1,	
+			rsvd2: 	1,
 			pcache: 1,	/* entry belongs to partial cache */
 			reqtype: 5,	/* Identifies type of request
 					 * See below for field values.
@@ -676,8 +676,8 @@
 #define	IIO_ICRB_REQ_WB		16	/* Request is Write back	*/
 #define	IIO_ICRB_REQ_DEX	17	/* Retained DEX Cache line	*/
 
-/* 
- * Fields in CRB Register C 
+/*
+ * Fields in CRB Register C
  */
 
 #ifndef __ASSEMBLY__
@@ -690,7 +690,7 @@
 			pricnt: 4,	/* Priority count sent with Read req */
 			pripsc: 4,	/* Priority Pre scalar 	*/
 			bteop:	1,	/* BTE Operation 	*/
-			push_be: 34,	/* Push address Byte enable 
+			push_be: 34,	/* Push address Byte enable
 					 * Holds push addr, if CRB is for BTE
 					 * If CRB belongs to Partial cache,
 					 * this contains byte enables bits
@@ -725,7 +725,7 @@
 	    u64	rsvd:	38,
 		toutvld: 1,	/* Timeout in progress for this CRB */
 		ctxtvld: 1,	/* Context field below is valid	*/
-		rsvd2:	1,	
+		rsvd2:	1,
 		context: 15, 	/* Bit vector:
 				 * Has a bit set for each CRB entry
 				 * which needs to be deallocated
@@ -762,7 +762,7 @@
 #define IIO_IBCT_0	0x410018	/* BTE control/terminate 0 */
 #define IIO_IBNA_0	0x410020	/* BTE notification address 0 */
 #define IIO_IBNR_0	IIO_IBNA_0
-#define IIO_IBIA_0	0x410028	/* BTE interrupt address 0 */	
+#define IIO_IBIA_0	0x410028	/* BTE interrupt address 0 */
 
 #define IIO_IBLS_1	0x420000	/* BTE length/status 1 */
 #define IIO_IBSA_1	0x420008	/* BTE source address 1 */
@@ -770,7 +770,7 @@
 #define IIO_IBCT_1	0x420018	/* BTE control/terminate 1 */
 #define IIO_IBNA_1	0x420020	/* BTE notification address 1 */
 #define IIO_IBNR_1	IIO_IBNA_1
-#define IIO_IBIA_1	0x420028	/* BTE interrupt address 1 */	
+#define IIO_IBIA_1	0x420028	/* BTE interrupt address 1 */
 
 /*
  * More miscellaneous registers
@@ -795,7 +795,7 @@
 #define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
 
 /*
- * IO PIO Read Table Entry format 
+ * IO PIO Read Table Entry format
  */
 
 #ifndef __ASSEMBLY__
@@ -830,7 +830,7 @@
 
 #ifndef __ASSEMBLY__
 /*
- * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are 
+ * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are
  * "Status" fields, and should only be used in case of clean up after errors.
  */
 
@@ -932,8 +932,8 @@
 	} iin_fmt;
 } hubii_idsr_t;
 #endif /* !__ASSEMBLY__ */
-	
-/* 
+
+/*
  * IO BTE Length/Status (IIO_IBLS) register bit field definitions
  */
 #define IBLS_BUSY		(0x1 << 20)
@@ -965,18 +965,18 @@
 #define HUB_WIDGET_ID_MIN	0x8
 #define HUB_WIDGET_ID_MAX	0xf
 
-#define HUB_WIDGET_PART_NUM	0xc101	
+#define HUB_WIDGET_PART_NUM	0xc101
 #define MAX_HUBS_PER_XBOW	2
 
-/* 
- * Get a hub's widget id from widget control register 
+/*
+ * Get a hub's widget id from widget control register
  */
-#define IIO_WCR_WID_GET(nasid)	(REMOTE_HUB_L(nasid, III_WCR) & 0xf) 
+#define IIO_WCR_WID_GET(nasid)	(REMOTE_HUB_L(nasid, III_WCR) & 0xf)
 #define IIO_WST_ERROR_MASK	(UINT64_CAST 1 << 32) /* Widget status error */
 
 /*
  * Number of credits Hub widget has while sending req/response to
- * xbow. 
+ * xbow.
  * Value of 3 is required by Xbow 1.1
  * We may be able to increase this to 4 with Xbow 1.2.
  */
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/sn0/hubmd.h linux-2.4.20-pre7/include/asm-mips64/sn/sn0/hubmd.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/sn0/hubmd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/sn0/hubmd.h	Thu Sep 12 20:01:49 2002
@@ -228,7 +228,7 @@
 #define MSU_SN0_SLOTID_MASK	(UINT64_CAST 7)
 #define MSU_SN00_SLOTID_SHFT	7
 #define MSU_SN00_SLOTID_MASK	(UINT64_CAST 0x80)
-	
+
 #define	MSU_PIMM_PSC_SHFT	4
 #define	MSU_PIMM_PSC_MASK	(0xf << MSU_PIMM_PSC_SHFT)
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/sn0/hubpi.h linux-2.4.20-pre7/include/asm-mips64/sn/sn0/hubpi.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/sn0/hubpi.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/sn/sn0/hubpi.h	Thu Sep 12 20:01:49 2002
@@ -136,8 +136,8 @@
 #define PI_ERR_INT_PEND		0x000400 /* Error Interrupt Pending	    */
 #define PI_ERR_INT_MASK_A	0x000408 /* Error Interrupt mask for CPU A  */
 #define PI_ERR_INT_MASK_B	0x000410 /* Error Interrupt mask for CPU B  */
-#define PI_ERR_STACK_ADDR_A	0x000418 /* Error stack address for CPU A   */ 
-#define PI_ERR_STACK_ADDR_B	0x000420 /* Error stack address for CPU B   */ 
+#define PI_ERR_STACK_ADDR_A	0x000418 /* Error stack address for CPU A   */
+#define PI_ERR_STACK_ADDR_B	0x000420 /* Error stack address for CPU B   */
 #define PI_ERR_STACK_SIZE	0x000428 /* Error Stack Size 		    */
 #define PI_ERR_STATUS0_A	0x000430 /* Error Status 0A 		    */
 #define PI_ERR_STATUS0_A_RCLR	0x000438 /* Error Status 0A clear on read   */
@@ -193,7 +193,7 @@
 
 
 /*
- * The following three macros define all possible error int pends. 
+ * The following three macros define all possible error int pends.
  */
 
 #define PI_FATAL_ERR_CPU_A	(PI_ERR_SYSSTATE_TAG_A 	| \
diff -urN linux-2.4.20-pre6/include/asm-mips64/sn/sn0/sn0_fru.h linux-2.4.20-pre7/include/asm-mips64/sn/sn0/sn0_fru.h
--- linux-2.4.20-pre6/include/asm-mips64/sn/sn0/sn0_fru.h	Sun Sep  9 10:43:02 2001
+++ linux-2.4.20-pre7/include/asm-mips64/sn/sn0/sn0_fru.h	Thu Sep 12 20:01:49 2002
@@ -17,11 +17,11 @@
 typedef unsigned char confidence_t;
 
 typedef struct kf_mem_s {
-	confidence_t km_confidence; /* confidence level that the memory is bad 
-				     * is this necessary ? 
+	confidence_t km_confidence; /* confidence level that the memory is bad
+				     * is this necessary ?
 				     */
-	confidence_t km_dimm[MAX_DIMMS];   
-	                            /* confidence level that dimm[i] is bad 
+	confidence_t km_dimm[MAX_DIMMS];
+	                            /* confidence level that dimm[i] is bad
 				     *I think this is the right number
 				     */
 
diff -urN linux-2.4.20-pre6/include/asm-mips64/softirq.h linux-2.4.20-pre7/include/asm-mips64/softirq.h
--- linux-2.4.20-pre6/include/asm-mips64/softirq.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/softirq.h	Thu Sep 12 20:01:49 2002
@@ -18,7 +18,7 @@
 	local_bh_count(cpu)++;
 	barrier();
 }
- 
+
 static inline void __cpu_bh_enable(int cpu)
 {
 	barrier();
diff -urN linux-2.4.20-pre6/include/asm-mips64/spinlock.h linux-2.4.20-pre7/include/asm-mips64/spinlock.h
--- linux-2.4.20-pre6/include/asm-mips64/spinlock.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/spinlock.h	Thu Sep 12 20:01:49 2002
@@ -55,7 +55,7 @@
 	".set\tnoreorder\t\t\t# spin_unlock\n\t"
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (lock->lock)
 	: "m" (lock->lock)
 	: "memory");
@@ -109,7 +109,7 @@
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock), "=&r" (tmp)
 	: "m" (rw->lock)
 	: "memory");
@@ -129,7 +129,7 @@
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock), "=&r" (tmp)
 	: "m" (rw->lock)
 	: "memory");
@@ -147,7 +147,7 @@
 	"sc\t%1, %0\n\t"
 	"beqz\t%1, 1b\n\t"
 	" sync\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock), "=&r" (tmp)
 	: "m" (rw->lock)
 	: "memory");
@@ -159,7 +159,7 @@
 	".set\tnoreorder\t\t\t# write_unlock\n\t"
 	"sync\n\t"
 	"sw\t$0, %0\n\t"
-	".set\treorder"	
+	".set\treorder"
 	: "=m" (rw->lock)
 	: "m" (rw->lock)
 	: "memory");
diff -urN linux-2.4.20-pre6/include/asm-mips64/stackframe.h linux-2.4.20-pre7/include/asm-mips64/stackframe.h
--- linux-2.4.20-pre6/include/asm-mips64/stackframe.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/stackframe.h	Thu Sep 12 20:01:49 2002
@@ -77,6 +77,9 @@
 
 #ifdef CONFIG_SMP
 		.macro	get_saved_sp	/* R10000 variation */
+#ifdef CONFIG_CPU_SB1
+		dmfc0	k1, CP0_WATCHLO
+#else
 		mfc0	k0, CP0_WATCHLO
 		mfc0	k1, CP0_WATCHHI
 		dsll32	k0, k0, 0	/* Get rid of sign extension */
@@ -85,12 +88,17 @@
 		or	k1, k1, k0
 		li	k0, K0BASE
 		or	k1, k1, k0
+#endif
 		.endm
 
 		.macro	set_saved_sp	stackp temp
+#ifdef CONFIG_CPU_SB1
+		dmtc0	\stackp, CP0_WATCHLO
+#else
 		mtc0	\stackp, CP0_WATCHLO
 		dsrl32	\temp, \stackp, 0
 		mtc0	\temp, CP0_WATCHHI
+#endif
 		.endm
 
 		.macro	declare_saved_sp
diff -urN linux-2.4.20-pre6/include/asm-mips64/system.h linux-2.4.20-pre7/include/asm-mips64/system.h
--- linux-2.4.20-pre6/include/asm-mips64/system.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/system.h	Thu Sep 12 20:01:49 2002
@@ -12,9 +12,12 @@
 
 #include <linux/config.h>
 #include <asm/sgidefs.h>
-#include <asm/ptrace.h>
+
 #include <linux/kernel.h>
 
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+
 __asm__ (
 	".macro\t__sti\n\t"
 	".set\tpush\n\t"
@@ -96,7 +99,7 @@
 	"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"	
+	".set\tpop\n\t"
 	".endm");
 
 #define __save_and_cli(x)						\
@@ -161,20 +164,37 @@
 #define local_irq_disable()	__cli()
 #define local_irq_enable()	__sti()
 
-/*
- * These are probably defined overly paranoid ...
- */
-#define mb()						\
-__asm__ __volatile__(					\
-	"# prevent instructions being moved around\n\t"	\
-	".set\tnoreorder\n\t"				\
-	"sync\n\t"					\
-	".set\treorder"					\
-	: /* no output */				\
-	: /* no input */				\
-	: "memory")
-#define rmb() mb()
-#define wmb() mb()
+#define __sync()				\
+	__asm__ __volatile__(			\
+		".set	push\n\t"		\
+		".set	noreorder\n\t"		\
+		"sync\n\t"			\
+		".set	pop"			\
+		: /* no output */		\
+		: /* no input */		\
+		: "memory")
+
+#define fast_wmb()	__sync()
+#define fast_rmb()	__sync()
+#define fast_mb()	__sync()
+#define fast_iob()				\
+	do {					\
+		__sync();			\
+		__asm__ __volatile__(		\
+			".set	push\n\t"	\
+			".set	noreorder\n\t"	\
+			"lw	$0,%0\n\t"	\
+			"nop\n\t"		\
+			".set	pop"		\
+			: /* no output */	\
+			: "m" (*(int *)KSEG1)	\
+			: "memory");		\
+	} while (0)
+
+#define wmb()		fast_wmb()
+#define rmb()		fast_rmb()
+#define mb()		fast_mb()
+#define iob()		fast_iob()
 
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
@@ -200,6 +220,8 @@
 
 #define prepare_to_switch()	do { } while(0)
 
+struct task_struct;
+
 extern asmlinkage void lazy_fpu_switch(void *, void *);
 extern asmlinkage void init_fpu(void);
 extern asmlinkage void save_fp(struct task_struct *);
@@ -282,6 +304,16 @@
 	return x;
 }
 
-extern void set_except_vector(int n, void *addr);
+extern void *set_except_vector(int n, void *addr);
+
+extern void __die(const char *, struct pt_regs *, const char *file,
+	const char *func, unsigned long line) __attribute__((noreturn));
+extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
+	const char *func, unsigned long line);
+
+#define die(msg, regs)							\
+	__die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
+#define die_if_kernel(msg, regs)					\
+	__die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__)
 
 #endif /* _ASM_SYSTEM_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/time.h linux-2.4.20-pre7/include/asm-mips64/time.h
--- linux-2.4.20-pre6/include/asm-mips64/time.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/time.h	Thu Sep 12 20:01:49 2002
@@ -23,7 +23,7 @@
 #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.
@@ -39,7 +39,7 @@
 extern void to_tm(unsigned long tim, struct rtc_time * tm);
 
 /*
- * do_gettimeoffset(). By default, this func pointer points to 
+ * 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.
  */
diff -urN linux-2.4.20-pre6/include/asm-mips64/timex.h linux-2.4.20-pre7/include/asm-mips64/timex.h
--- linux-2.4.20-pre6/include/asm-mips64/timex.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/asm-mips64/timex.h	Thu Sep 12 20:01:49 2002
@@ -20,7 +20,7 @@
  * Standard way to access the cycle counter.
  * Currently only used on SMP for scheduling.
  *
- * Only the low 32 bits are available as a continuously counting entity. 
+ * Only the low 32 bits are available as a continuously counting entity.
  * But this only means we'll force a reschedule every 8 seconds or so,
  * which isn't an evil thing.
  *
diff -urN linux-2.4.20-pre6/include/asm-mips64/types.h linux-2.4.20-pre7/include/asm-mips64/types.h
--- linux-2.4.20-pre6/include/asm-mips64/types.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/types.h	Thu Sep 12 20:01:49 2002
@@ -31,12 +31,12 @@
 typedef unsigned long __u64;
 
 #else
- 
+
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 typedef __signed__ long long __s64;
 typedef unsigned long long __u64;
 #endif
- 
+
 #endif
 
 /*
diff -urN linux-2.4.20-pre6/include/asm-mips64/uaccess.h linux-2.4.20-pre7/include/asm-mips64/uaccess.h
--- linux-2.4.20-pre6/include/asm-mips64/uaccess.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/uaccess.h	Thu Sep 12 20:01:49 2002
@@ -425,7 +425,7 @@
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, %2\n\t"
-		__MODULE_JAL(__strlen_user_nocheck_asm)
+		__MODULE_JAL(__strnlen_user_nocheck_asm)
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s), "r" (n)
@@ -441,7 +441,7 @@
 	__asm__ __volatile__(
 		"move\t$4, %1\n\t"
 		"move\t$5, %2\n\t"
-		__MODULE_JAL(__strlen_user_asm)
+		__MODULE_JAL(__strnlen_user_asm)
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s), "r" (n)
diff -urN linux-2.4.20-pre6/include/asm-mips64/unaligned.h linux-2.4.20-pre7/include/asm-mips64/unaligned.h
--- linux-2.4.20-pre6/include/asm-mips64/unaligned.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-mips64/unaligned.h	Thu Sep 12 20:01:49 2002
@@ -88,8 +88,8 @@
  * get_unaligned - get value from possibly mis-aligned location
  * @ptr: pointer to value
  *
- * This macro should be used for accessing values larger in size than 
- * single bytes at locations that are expected to be improperly aligned, 
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
  * e.g. retrieving a u16 value from a location not u16-aligned.
  *
  * Note that unaligned accesses can be very expensive on some architectures.
@@ -124,8 +124,8 @@
  * @val: value to place
  * @ptr: pointer to location
  *
- * This macro should be used for placing values larger in size than 
- * single bytes at locations that are expected to be improperly aligned, 
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
  * e.g. writing a u16 value to a location not u16-aligned.
  *
  * Note that unaligned accesses can be very expensive on some architectures.
diff -urN linux-2.4.20-pre6/include/asm-mips64/war.h linux-2.4.20-pre7/include/asm-mips64/war.h
--- linux-2.4.20-pre6/include/asm-mips64/war.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/war.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,70 @@
+/*
+ * This file is subject to 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
+
+#include <linux/config.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
+ */
+#undef R4600_V1_HIT_DCACHE_WAR	/* Not used yet in 64-bit kernel */
+
+
+/*
+ * 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.)
+ */
+#undef R4600_V2_HIT_CACHEOP_WAR	/* Not used yet in 64-bit kernel */
+
+#ifdef CONFIG_CPU_R5432
+
+/*
+ * When an interrupt happens on a CP0 register read instruction, CPU may
+ * lock up or read corrupted values of CP0 registers after it enters
+ * the exception handler.
+ *
+ * This workaround makes sure that we read a "safe" CP0 register as the
+ * first thing in the exception handler, which breaks one of the
+ * pre-conditions for this problem.
+ */
+#define	R5432_CP0_INTERRUPT_WAR
+
+#endif
+
+#endif /* _ASM_WAR_H */
diff -urN linux-2.4.20-pre6/include/asm-mips64/wbflush.h linux-2.4.20-pre7/include/asm-mips64/wbflush.h
--- linux-2.4.20-pre6/include/asm-mips64/wbflush.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/asm-mips64/wbflush.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,18 @@
+/*
+ * Header file for using the wbflush routine
+ *
+ * This file is subject to 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 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#ifndef __ASM_MIPS64_WBFLUSH_H
+#define __ASM_MIPS64_WBFLUSH_H
+
+#define wbflush_setup() do { } while (0)
+
+#define wbflush() fast_iob()
+
+#endif /* __ASM_MIPS64_WBFLUSH_H */
diff -urN linux-2.4.20-pre6/include/asm-ppc/gg2.h linux-2.4.20-pre7/include/asm-ppc/gg2.h
--- linux-2.4.20-pre6/include/asm-ppc/gg2.h	Mon May 21 15:02:06 2001
+++ linux-2.4.20-pre7/include/asm-ppc/gg2.h	Thu Sep 12 20:01:49 2002
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.gg2.h 1.5 05/17/01 18:14:24 cort
+ * BK Id: %F% %I% %G% %U% %#%
  */
 /*
  *  asm-ppc/gg2.h -- VLSI VAS96011/12 `Golden Gate 2' register definitions
@@ -37,6 +37,8 @@
      *  GG2 specific PCI Registers
      */
 
+extern unsigned long gg2_pci_config_base;	/* kernel virtual address */
+
 #define GG2_PCI_BUSNO		0x40	/* Bus number */
 #define GG2_PCI_SUBBUSNO	0x41	/* Subordinate bus number */
 #define GG2_PCI_DISCCTR		0x42	/* Disconnect counter */
diff -urN linux-2.4.20-pre6/include/asm-ppc/unistd.h linux-2.4.20-pre7/include/asm-ppc/unistd.h
--- linux-2.4.20-pre6/include/asm-ppc/unistd.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre7/include/asm-ppc/unistd.h	Thu Sep 12 20:01:49 2002
@@ -216,6 +216,31 @@
 #define __NR_mincore		206
 #define __NR_gettid		207
 #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
+#if 0
+#define __NR_futex		221
+#define __NR_sched_setaffinity	222
+#define __NR_sched_getaffinity	223
+#define __NR_security		224
+#define __NR_tuxcall		225
+#define __NR_sendfile64		226
+#define __NR_io_setup		227
+#define __NR_io_destroy		228
+#define __NR_io_getevents	229
+#define __NR_io_submit		230
+#define __NR_io_cancel		231
+#endif
 
 #define __NR(n)	#n
 
diff -urN linux-2.4.20-pre6/include/linux/cobalt-nvram.h linux-2.4.20-pre7/include/linux/cobalt-nvram.h
--- linux-2.4.20-pre6/include/linux/cobalt-nvram.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre7/include/linux/cobalt-nvram.h	Thu Sep 12 20:01:49 2002
@@ -0,0 +1,109 @@
+/*
+ * $Id: cobalt-nvram.h,v 1.20 2001/10/17 23:16:55 thockin Exp $
+ * cobalt-nvram.h : defines for the various fields in the cobalt NVRAM
+ *
+ * Copyright 2001,2002 Sun Microsystems, Inc.
+ */
+
+#ifndef COBALT_NVRAM_H
+#define COBALT_NVRAM_H
+
+#include <linux/nvram.h>
+
+#define COBT_CMOS_INFO_MAX		0x7f	/* top address allowed */
+#define COBT_CMOS_BIOS_DRIVE_INFO	0x12	/* drive info would go here */
+
+#define COBT_CMOS_CKS_START		NVRAM_OFFSET(0x0e)
+#define COBT_CMOS_CKS_END		NVRAM_OFFSET(0x7f)
+
+/* flag bytes - 16 flags for now, leave room for more */
+#define COBT_CMOS_FLAG_BYTE_0		NVRAM_OFFSET(0x10)
+#define COBT_CMOS_FLAG_BYTE_1		NVRAM_OFFSET(0x11)
+
+/* flags in flag bytes - up to 16 */
+#define COBT_CMOS_FLAG_MIN		0x0001
+#define COBT_CMOS_CONSOLE_FLAG		0x0001 /* console on/off */
+#define COBT_CMOS_DEBUG_FLAG		0x0002 /* ROM debug messages */
+#define COBT_CMOS_AUTO_PROMPT_FLAG	0x0004 /* boot to ROM prompt? */
+#define COBT_CMOS_CLEAN_BOOT_FLAG	0x0008 /* set by a clean shutdown */
+#define COBT_CMOS_HW_NOPROBE_FLAG	0x0010 /* go easy on the probing */
+#define COBT_CMOS_SYSFAULT_FLAG		0x0020 /* system fault detected */
+#define COBT_CMOS_OOPSPANIC_FLAG	0x0040 /* panic on oops */
+#define COBT_CMOS_DELAY_CACHE_FLAG	0x0080 /* delay cache initialization */
+#define COBT_CMOS_NOLOGO_FLAG		0x0100 /* hide "C" logo @ boot */
+#define COBT_CMOS_VERSION_FLAG		0x0200 /* the version field is valid */
+#define COBT_CMOS_FLAG_MAX		0x0200
+
+/* leave byte 0x12 blank - Linux looks for drive info here */
+
+/* CMOS structure version, valid if COBT_CMOS_VERSION_FLAG is true */
+#define COBT_CMOS_VERSION		NVRAM_OFFSET(0x13)
+#define COBT_CMOS_VER_BTOCODE		1 /* min. version needed for btocode */
+
+/* index of default boot method */
+#define COBT_CMOS_BOOT_METHOD		NVRAM_OFFSET(0x20)
+#define COBT_CMOS_BOOT_METHOD_DISK	0
+#define COBT_CMOS_BOOT_METHOD_ROM	1
+#define COBT_CMOS_BOOT_METHOD_NET	2
+
+#define COBT_CMOS_BOOT_DEV_MIN		NVRAM_OFFSET(0x21)
+/* major #, minor # of first through fourth boot device */
+#define COBT_CMOS_BOOT_DEV0_MAJ		NVRAM_OFFSET(0x21)
+#define COBT_CMOS_BOOT_DEV0_MIN		NVRAM_OFFSET(0x22)
+#define COBT_CMOS_BOOT_DEV1_MAJ		NVRAM_OFFSET(0x23)
+#define COBT_CMOS_BOOT_DEV1_MIN		NVRAM_OFFSET(0x24)
+#define COBT_CMOS_BOOT_DEV2_MAJ		NVRAM_OFFSET(0x25)
+#define COBT_CMOS_BOOT_DEV2_MIN		NVRAM_OFFSET(0x26)
+#define COBT_CMOS_BOOT_DEV3_MAJ		NVRAM_OFFSET(0x27)
+#define COBT_CMOS_BOOT_DEV3_MIN		NVRAM_OFFSET(0x28)
+#define COBT_CMOS_BOOT_DEV_MAX		NVRAM_OFFSET(0x28)
+
+/* checksum of bytes 0xe-0x7f */
+#define COBT_CMOS_CHECKSUM		NVRAM_OFFSET(0x2e)
+
+/* running uptime counter, units of 5 minutes (32 bits =~ 41000 years) */
+#define COBT_CMOS_UPTIME_0		NVRAM_OFFSET(0x30)
+#define COBT_CMOS_UPTIME_1		NVRAM_OFFSET(0x31)
+#define COBT_CMOS_UPTIME_2		NVRAM_OFFSET(0x32)
+#define COBT_CMOS_UPTIME_3		NVRAM_OFFSET(0x33)
+
+/* count of successful boots (32 bits) */
+#define COBT_CMOS_BOOTCOUNT_0		NVRAM_OFFSET(0x38)
+#define COBT_CMOS_BOOTCOUNT_1		NVRAM_OFFSET(0x39)
+#define COBT_CMOS_BOOTCOUNT_2		NVRAM_OFFSET(0x3a)
+#define COBT_CMOS_BOOTCOUNT_3		NVRAM_OFFSET(0x3b)
+
+/* 13 bytes: system serial number, same as on the back of the system */
+#define COBT_CMOS_SYS_SERNUM_LEN	13
+#define COBT_CMOS_SYS_SERNUM_0		NVRAM_OFFSET(0x40)
+#define COBT_CMOS_SYS_SERNUM_1		NVRAM_OFFSET(0x41)
+#define COBT_CMOS_SYS_SERNUM_2		NVRAM_OFFSET(0x42)
+#define COBT_CMOS_SYS_SERNUM_3		NVRAM_OFFSET(0x43)
+#define COBT_CMOS_SYS_SERNUM_4		NVRAM_OFFSET(0x44)
+#define COBT_CMOS_SYS_SERNUM_5		NVRAM_OFFSET(0x45)
+#define COBT_CMOS_SYS_SERNUM_6		NVRAM_OFFSET(0x46)
+#define COBT_CMOS_SYS_SERNUM_7		NVRAM_OFFSET(0x47)
+#define COBT_CMOS_SYS_SERNUM_8		NVRAM_OFFSET(0x48)
+#define COBT_CMOS_SYS_SERNUM_9		NVRAM_OFFSET(0x49)
+#define COBT_CMOS_SYS_SERNUM_10		NVRAM_OFFSET(0x4a)
+#define COBT_CMOS_SYS_SERNUM_11		NVRAM_OFFSET(0x4b)
+#define COBT_CMOS_SYS_SERNUM_12		NVRAM_OFFSET(0x4c)
+/* checksum for serial num - 1 byte */
+#define COBT_CMOS_SYS_SERNUM_CSUM	NVRAM_OFFSET(0x4f)
+
+#define COBT_CMOS_ROM_REV_MAJ		NVRAM_OFFSET(0x50)
+#define COBT_CMOS_ROM_REV_MIN		NVRAM_OFFSET(0x51)
+#define COBT_CMOS_ROM_REV_REV		NVRAM_OFFSET(0x52)
+
+#define COBT_CMOS_BTO_CODE_0		NVRAM_OFFSET(0x53)
+#define COBT_CMOS_BTO_CODE_1		NVRAM_OFFSET(0x54)
+#define COBT_CMOS_BTO_CODE_2		NVRAM_OFFSET(0x55)
+#define COBT_CMOS_BTO_CODE_3		NVRAM_OFFSET(0x56)
+
+#define COBT_CMOS_BTO_IP_CSUM		NVRAM_OFFSET(0x57)
+#define COBT_CMOS_BTO_IP_0		NVRAM_OFFSET(0x58)
+#define COBT_CMOS_BTO_IP_1		NVRAM_OFFSET(0x59)
+#define COBT_CMOS_BTO_IP_2		NVRAM_OFFSET(0x5a)
+#define COBT_CMOS_BTO_IP_3		NVRAM_OFFSET(0x5b)
+
+#endif /* COBALT_NVRAM_H */
diff -urN linux-2.4.20-pre6/include/linux/nvram.h linux-2.4.20-pre7/include/linux/nvram.h
--- linux-2.4.20-pre6/include/linux/nvram.h	Fri Oct 29 10:58:00 1999
+++ linux-2.4.20-pre7/include/linux/nvram.h	Thu Sep 12 20:01:49 2002
@@ -4,14 +4,24 @@
 #include <linux/ioctl.h>
 
 /* /dev/nvram ioctls */
-#define NVRAM_INIT		_IO('p', 0x40) /* initialize NVRAM and set checksum */
-#define	NVRAM_SETCKS	_IO('p', 0x41) /* recalculate checksum */
+#define NVRAM_INIT	_IO('p', 0x40) /* initialize NVRAM and set checksum */
+#define NVRAM_SETCKS	_IO('p', 0x41) /* recalculate checksum */
+
+/* for all current systems, this is where NVRAM starts */
+#define NVRAM_FIRST_BYTE    14
+/* all these functions expect an NVRAM offset, not an absolute */
+#define NVRAM_OFFSET(x)   ((x)-NVRAM_FIRST_BYTE)
 
 #ifdef __KERNEL__
-extern unsigned char nvram_read_byte( int i );
-extern void nvram_write_byte( unsigned char c, int i );
-extern int nvram_check_checksum( void );
-extern void nvram_set_checksum( void );
+/* __foo is foo without grabbing the rtc_lock - get it yourself */
+extern unsigned char __nvram_read_byte(int i);
+extern unsigned char nvram_read_byte(int i);
+extern void __nvram_write_byte(unsigned char c, int i);
+extern void nvram_write_byte(unsigned char c, int i);
+extern int __nvram_check_checksum(void);
+extern int nvram_check_checksum(void);
+extern void __nvram_set_checksum(void);
+extern void nvram_set_checksum(void);
 #endif
 
 #endif  /* _LINUX_NVRAM_H */
diff -urN linux-2.4.20-pre6/include/linux/pagemap.h linux-2.4.20-pre7/include/linux/pagemap.h
--- linux-2.4.20-pre6/include/linux/pagemap.h	Mon Feb 25 11:38:13 2002
+++ linux-2.4.20-pre7/include/linux/pagemap.h	Thu Sep 12 20:01:49 2002
@@ -97,7 +97,15 @@
 		___wait_on_page(page);
 }
 
-extern struct page * grab_cache_page (struct address_space *, unsigned long);
+/*
+ * Returns locked page at given index in given cache, creating it if needed.
+ */
+static inline struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
+{
+	return find_or_create_page(mapping, index, mapping->gfp_mask);
+}
+
+
 extern struct page * grab_cache_page_nowait (struct address_space *, unsigned long);
 
 typedef int filler_t(void *, struct page*);
diff -urN linux-2.4.20-pre6/include/linux/pci.h linux-2.4.20-pre7/include/linux/pci.h
--- linux-2.4.20-pre6/include/linux/pci.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/linux/pci.h	Thu Sep 12 20:01:49 2002
@@ -382,6 +382,9 @@
 	int		ro;		/* ISAPnP: read only */
 	unsigned short	regs;		/* ISAPnP: supported registers */
 
+	/* These fields are used by common fixups */
+	unsigned short	transparent:1;	/* Transparent PCI bridge */
+
 	int (*prepare)(struct pci_dev *dev);	/* ISAPnP hooks */
 	int (*activate)(struct pci_dev *dev);
 	int (*deactivate)(struct pci_dev *dev);
diff -urN linux-2.4.20-pre6/include/linux/pci_ids.h linux-2.4.20-pre7/include/linux/pci_ids.h
--- linux-2.4.20-pre6/include/linux/pci_ids.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/linux/pci_ids.h	Thu Sep 12 20:01:49 2002
@@ -813,6 +813,7 @@
 #define PCI_DEVICE_ID_AL_M1523		0x1523
 #define PCI_DEVICE_ID_AL_M1531		0x1531
 #define PCI_DEVICE_ID_AL_M1533		0x1533
+#define PCI_DEVICE_ID_AL_M1535 		0x1535
 #define PCI_DEVICE_ID_AL_M1541		0x1541
 #define PCI_DEVICE_ID_AL_M1621          0x1621
 #define PCI_DEVICE_ID_AL_M1631          0x1631
diff -urN linux-2.4.20-pre6/include/linux/reiserfs_fs.h linux-2.4.20-pre7/include/linux/reiserfs_fs.h
--- linux-2.4.20-pre6/include/linux/reiserfs_fs.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/linux/reiserfs_fs.h	Thu Sep 12 20:01:49 2002
@@ -2008,7 +2008,6 @@
 #endif
 void reiserfs_claim_blocks_to_be_allocated( struct super_block *sb, int blocks);
 void reiserfs_release_claimed_blocks( struct super_block *sb, int blocks);
-int reiserfs_can_fit_pages(struct super_block *sb);
 
 /* hashes.c */
 __u32 keyed_hash (const signed char *msg, int len);
diff -urN linux-2.4.20-pre6/include/linux/reiserfs_fs_sb.h linux-2.4.20-pre7/include/linux/reiserfs_fs_sb.h
--- linux-2.4.20-pre6/include/linux/reiserfs_fs_sb.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/linux/reiserfs_fs_sb.h	Thu Sep 12 20:01:49 2002
@@ -466,7 +466,6 @@
     reiserfs_proc_info_data_t s_proc_info_data;
     struct proc_dir_entry *procdir;
     int reserved_blocks; /* amount of blocks reserved for further allocations */
-    spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
 };
 
 /* Definitions of reiserfs on-disk properties: */
diff -urN linux-2.4.20-pre6/include/linux/swap.h linux-2.4.20-pre7/include/linux/swap.h
--- linux-2.4.20-pre6/include/linux/swap.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/linux/swap.h	Thu Sep 12 20:01:49 2002
@@ -114,8 +114,8 @@
 
 /* linux/mm/vmscan.c */
 extern wait_queue_head_t kswapd_wait;
-extern int FASTCALL(try_to_free_pages(zone_t *, unsigned int, unsigned int));
-extern int FASTCALL(try_to_free_pages_nozone(unsigned int));
+extern int FASTCALL(try_to_free_pages_zone(zone_t *, unsigned int));
+extern int FASTCALL(try_to_free_pages(unsigned int));
 
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *);
diff -urN linux-2.4.20-pre6/include/linux/usb.h linux-2.4.20-pre7/include/linux/usb.h
--- linux-2.4.20-pre6/include/linux/usb.h	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/include/linux/usb.h	Thu Sep 12 20:01:49 2002
@@ -437,6 +437,7 @@
  * urb->transfer_flags:
  */
 #define USB_DISABLE_SPD		0x0001
+#define URB_SHORT_NOT_OK	USB_DISABLE_SPD
 #define USB_ISO_ASAP		0x0002
 #define USB_ASYNC_UNLINK	0x0008
 #define USB_QUEUE_BULK		0x0010
@@ -454,6 +455,8 @@
 	unsigned int status;
 };
 
+#define usb_iso_packet_descriptor	iso_packet_descriptor
+
 struct urb;
 typedef void (*usb_complete_t)(struct urb *);
 
@@ -468,10 +471,12 @@
 	int status;			// returned status
 	unsigned int transfer_flags;	// USB_DISABLE_SPD | USB_ISO_ASAP | etc.
 	void *transfer_buffer;		// associated data buffer
+	dma_addr_t transfer_dma;	// dma addr for transfer_buffer
 	int transfer_buffer_length;	// data buffer length
 	int actual_length;              // actual data buffer length	
 	int bandwidth;			// bandwidth for this transfer request (INT or ISO)
 	unsigned char *setup_packet;	// setup packet (control only)
+	dma_addr_t setup_dma;		// dma addr for setup_packet
 	//
 	int start_frame;		// start frame (iso/irq only)
 	int number_of_packets;		// number of packets in this request (iso)
@@ -723,6 +728,7 @@
  */
 struct usb_bus {
 	int busnum;			/* Bus number (in order of reg) */
+	char *bus_name;			/* stable id (PCI slot_name etc) */
 
 #ifdef DEVNUM_ROUND_ROBIN
 	int devnum_next;                /* Next open device number in round-robin allocation */
@@ -771,7 +777,8 @@
 #define USB_MAXCHILDREN		(16)
 
 struct usb_device {
-	int devnum;			/* Device number on USB bus */
+	int		devnum;		/* Address on USB bus */
+	char		devpath [16];	/* Use in messages: /port/port/... */
 
 	enum {
 		USB_SPEED_UNKNOWN = 0,			/* enumerating */
@@ -846,10 +853,6 @@
 extern void usb_inc_dev_use(struct usb_device *);
 #define usb_dec_dev_use usb_free_dev
 
-extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
-extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc);
-extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc);
-
 extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout);
 
 extern int usb_root_hub_string(int id, int serial, char *type, __u8 *data, int len);
@@ -860,6 +863,42 @@
 
 int usb_get_current_frame_number (struct usb_device *usb_dev);
 
+
+/**
+ * usb_make_path - returns stable device path in the usb tree
+ * @dev: the device whose path is being constructed
+ * @buf: where to put the string
+ * @size: how big is "buf"?
+ *
+ * Returns length of the string (> 0) or negative if size was too small.
+ *
+ * This identifier is intended to be "stable", reflecting physical paths in
+ * hardware such as physical bus addresses for host controllers or ports on
+ * USB hubs.  That makes it stay the same until systems are physically
+ * reconfigured, by re-cabling a tree of USB devices or by moving USB host
+ * controllers.  Adding and removing devices, including virtual root hubs
+ * in host controller driver modules, does not change these path identifers;
+ * neither does rebooting or re-enumerating.  These are more useful identifiers
+ * than changeable ("unstable") ones like bus numbers or device addresses.
+ * (The stability of the id depends on stability of the bus_name associated
+ * with the bus the device uses; that is normally stable.)
+ *
+ * With a partial exception for devices connected to USB 2.0 root hubs, these
+ * identifiers are also predictable.  So long as the device tree isn't changed,
+ * plugging any USB device into a given hub port always gives it the same path.
+ * Because of the use of "companion" controllers, devices connected to ports on
+ * USB 2.0 root hubs (EHCI host controllers) will get one path ID if they are
+ * high speed, and a different one if they are full or low speed.
+ */
+static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
+{
+	int actual;
+	actual = snprintf (buf, size, "usb-%s-%s",
+		dev->bus->bus_name, dev->devpath);
+	return (actual >= size) ? -1 : actual;
+}
+
+
 /*
  * Calling this entity a "pipe" is glorifying it. A USB pipe
  * is something embarrassingly simple: it basically consists
@@ -986,26 +1025,6 @@
 	__usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,type,(void**)ptr)
 
 /*
- * Some USB bandwidth allocation constants.
- */
-#define BW_HOST_DELAY	1000L		/* nanoseconds */
-#define BW_HUB_LS_SETUP	333L		/* nanoseconds */
-                        /* 4 full-speed bit times (est.) */
-
-#define FRAME_TIME_BITS         12000L		/* frame = 1 millisecond */
-#define FRAME_TIME_MAX_BITS_ALLOC	(90L * FRAME_TIME_BITS / 100L)
-#define FRAME_TIME_USECS	1000L
-#define FRAME_TIME_MAX_USECS_ALLOC	(90L * FRAME_TIME_USECS / 100L)
-
-#define BitTime(bytecount)  (7 * 8 * bytecount / 6)  /* with integer truncation */
-		/* Trying not to use worst-case bit-stuffing
-                   of (7/6 * 8 * bytecount) = 9.33 * bytecount */
-		/* bytecount = data payload byte count */
-
-#define NS_TO_US(ns)	((ns + 500L) / 1000L)
-			/* convert & round nanoseconds to microseconds */
-
-/*
  * Debugging helpers..
  */
 void usb_show_device_descriptor(struct usb_device_descriptor *);
diff -urN linux-2.4.20-pre6/init/do_mounts.c linux-2.4.20-pre7/init/do_mounts.c
--- linux-2.4.20-pre6/init/do_mounts.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/init/do_mounts.c	Thu Sep 12 20:01:49 2002
@@ -20,17 +20,17 @@
 
 extern int get_filesystem_list(char * buf);
 
-asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
+extern 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_fchdir(int fd);
-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);
+extern asmlinkage long sys_mkdir(const char *name, int mode);
+extern asmlinkage long sys_chdir(const char *name);
+extern asmlinkage long sys_fchdir(int fd);
+extern asmlinkage long sys_chroot(const char *name);
+extern asmlinkage long sys_unlink(const char *name);
+extern asmlinkage long sys_symlink(const char *old, const char *new);
+extern asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
+extern asmlinkage long sys_umount(char *name, int flags);
+extern 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 */
diff -urN linux-2.4.20-pre6/kernel/ksyms.c linux-2.4.20-pre7/kernel/ksyms.c
--- linux-2.4.20-pre6/kernel/ksyms.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/kernel/ksyms.c	Thu Sep 12 20:01:49 2002
@@ -215,7 +215,6 @@
 EXPORT_SYMBOL(generic_cont_expand);
 EXPORT_SYMBOL(cont_prepare_write);
 EXPORT_SYMBOL(generic_commit_write);
-EXPORT_SYMBOL(block_commit_write);
 EXPORT_SYMBOL(block_truncate_page);
 EXPORT_SYMBOL(generic_block_bmap);
 EXPORT_SYMBOL(generic_file_read);
@@ -262,7 +261,7 @@
 EXPORT_SYMBOL(ROOT_DEV);
 EXPORT_SYMBOL(__find_get_page);
 EXPORT_SYMBOL(__find_lock_page);
-EXPORT_SYMBOL(grab_cache_page);
+EXPORT_SYMBOL(find_or_create_page);
 EXPORT_SYMBOL(grab_cache_page_nowait);
 EXPORT_SYMBOL(read_cache_page);
 EXPORT_SYMBOL(set_page_dirty);
@@ -532,8 +531,6 @@
 EXPORT_SYMBOL(is_bad_inode);
 EXPORT_SYMBOL(event);
 EXPORT_SYMBOL(brw_page);
-EXPORT_SYMBOL(generic_osync_inode);
-EXPORT_SYMBOL(remove_suid);
 
 #ifdef CONFIG_UID16
 EXPORT_SYMBOL(overflowuid);
diff -urN linux-2.4.20-pre6/mm/filemap.c linux-2.4.20-pre7/mm/filemap.c
--- linux-2.4.20-pre6/mm/filemap.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/mm/filemap.c	Thu Sep 12 20:01:49 2002
@@ -1029,15 +1029,6 @@
 }
 
 /*
- * Returns locked page at given index in given cache, creating it if needed.
- */
-struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
-{
-	return find_or_create_page(mapping, index, mapping->gfp_mask);
-}
-
-
-/*
  * Same as grab_cache_page, but do not wait if the page is unavailable.
  * This is intended for speculative data generators, where the data can
  * be regenerated if the page couldn't be grabbed.  This routine should
@@ -2906,7 +2897,7 @@
 	return page;
 }
 
-void remove_suid(struct inode *inode)
+inline void remove_suid(struct inode *inode)
 {
 	unsigned int mode;
 
diff -urN linux-2.4.20-pre6/mm/page_alloc.c linux-2.4.20-pre7/mm/page_alloc.c
--- linux-2.4.20-pre6/mm/page_alloc.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/mm/page_alloc.c	Thu Sep 12 20:01:49 2002
@@ -263,7 +263,7 @@
 	current->allocation_order = order;
 	current->flags |= PF_MEMALLOC | PF_FREE_PAGES;
 
-	__freed = try_to_free_pages(classzone, gfp_mask, order);
+	__freed = try_to_free_pages_zone(classzone, gfp_mask);
 
 	current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES);
 
@@ -511,25 +511,6 @@
 }
 #endif
 
-int try_to_free_pages_nozone(unsigned int gfp_mask)
-{
-	pg_data_t *pgdat;
-	zonelist_t *zonelist;
-	unsigned long pf_free_pages;
-	int error = 0;
-
-	pf_free_pages = current->flags & PF_FREE_PAGES;
-	current->flags &= ~PF_FREE_PAGES;
-
-	for_each_pgdat(pgdat) {
-		zonelist = pgdat->node_zonelists + (gfp_mask & GFP_ZONEMASK);
-		error |= try_to_free_pages(zonelist->zones[0], gfp_mask, 0);
-	}
-
-	current->flags |= pf_free_pages;
-	return error;
-}
-
 #define K(x) ((x) << (PAGE_SHIFT-10))
 
 /*
diff -urN linux-2.4.20-pre6/mm/vmscan.c linux-2.4.20-pre7/mm/vmscan.c
--- linux-2.4.20-pre6/mm/vmscan.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/mm/vmscan.c	Thu Sep 12 20:01:49 2002
@@ -584,7 +584,7 @@
 	return nr_pages;
 }
 
-int try_to_free_pages(zone_t *classzone, unsigned int gfp_mask, unsigned int order)
+int try_to_free_pages_zone(zone_t *classzone, unsigned int gfp_mask)
 {
 	int priority = DEF_PRIORITY;
 	int nr_pages = SWAP_CLUSTER_MAX;
@@ -604,6 +604,25 @@
 	return 0;
 }
 
+int try_to_free_pages(unsigned int gfp_mask)
+{
+	pg_data_t *pgdat;
+	zonelist_t *zonelist;
+	unsigned long pf_free_pages;
+	int error = 0;
+
+	pf_free_pages = current->flags & PF_FREE_PAGES;
+	current->flags &= ~PF_FREE_PAGES;
+
+	for_each_pgdat(pgdat) {
+		zonelist = pgdat->node_zonelists + (gfp_mask & GFP_ZONEMASK);
+		error |= try_to_free_pages_zone(zonelist->zones[0], gfp_mask);
+	}
+
+	current->flags |= pf_free_pages;
+	return error;
+}
+
 DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
 
 static int check_classzone_need_balance(zone_t * classzone)
@@ -630,7 +649,7 @@
 			schedule();
 		if (!zone->need_balance)
 			continue;
-		if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) {
+		if (!try_to_free_pages_zone(zone, GFP_KSWAPD)) {
 			zone->need_balance = 0;
 			__set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(HZ);
diff -urN linux-2.4.20-pre6/net/bluetooth/hci_core.c linux-2.4.20-pre7/net/bluetooth/hci_core.c
--- linux-2.4.20-pre6/net/bluetooth/hci_core.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/net/bluetooth/hci_core.c	Thu Sep 12 20:01:49 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI Core.
  *
- * $Id: hci_core.c,v 1.11 2002/07/04 00:25:11 maxk Exp $
+ * $Id: hci_core.c,v 1.14 2002/08/26 16:57:57 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -1164,6 +1164,25 @@
 	return conn;
 }
 
+static inline void hci_acl_tx_to(struct hci_dev *hdev)
+{
+	struct conn_hash *h = &hdev->conn_hash;
+	struct list_head *p;
+	struct hci_conn  *c;
+
+	BT_ERR("%s ACL tx timeout", hdev->name);
+
+	/* Kill stalled connections */
+	list_for_each(p, &h->list) {
+		c = list_entry(p, struct hci_conn, list);
+		if (c->type == ACL_LINK && c->sent) {
+			BT_ERR("%s killing stalled ACL connection %s",
+				hdev->name, batostr(&c->dst));
+			hci_acl_disconn(c, 0x13);
+		}
+	}
+}
+
 static inline void hci_sched_acl(struct hci_dev *hdev)
 {
 	struct hci_conn *conn;
@@ -1174,10 +1193,8 @@
 
 	/* 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++;
-	}
+	if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
+		hci_acl_tx_to(hdev);
 
 	while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
 		while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
diff -urN linux-2.4.20-pre6/net/bluetooth/l2cap.c linux-2.4.20-pre7/net/bluetooth/l2cap.c
--- linux-2.4.20-pre6/net/bluetooth/l2cap.c	Thu Sep 12 20:01:36 2002
+++ linux-2.4.20-pre7/net/bluetooth/l2cap.c	Thu Sep 12 20:01:49 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ L2CAP core and sockets.
  *
- * $Id: l2cap.c,v 1.13 2002/07/27 19:04:15 maxk Exp $
+ * $Id: l2cap.c,v 1.15 2002/09/09 01:14:52 maxk Exp $
  */
 #define VERSION "2.1"
 
@@ -1933,8 +1933,8 @@
 	BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
 
 	if (flags & ACL_START) {
-		int flen, tlen, size;
-		l2cap_hdr *lh;
+		l2cap_hdr *hdr;
+		int len;
 
 		if (conn->rx_len) {
 			BT_ERR("Unexpected start frame (len %d)", skb->len);
@@ -1943,30 +1943,28 @@
 			conn->rx_len = 0;
 		}
 
-		if (skb->len < L2CAP_HDR_SIZE) {
+		if (skb->len < 2) {
 			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;
+		hdr = (l2cap_hdr *) skb->data;
+		len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
 
-		BT_DBG("Start: total len %d, frag len %d", tlen, flen);
+		BT_DBG("Start: total len %d, frag len %d", len, skb->len);
 
-		if (flen == tlen) {
+		if (len == skb->len) {
 			/* 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)))
+		if (!(conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC)))
 			goto drop;
 
 		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-		conn->rx_len = tlen - flen;
+		conn->rx_len = len - skb->len;
 	} else {
 		BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
 
