diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/CREDITS linux-bk/CREDITS
--- linux-2.4.19/CREDITS	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/CREDITS	2002-11-22 15:35:25.000000000 +0000
@@ -704,6 +704,11 @@
 S: Warrendale, Pennsylvania 15086
 S: USA
 
+N: Martin Devera
+E: devik@cdi.cz
+W: http://luxik.cdi.cz/~devik/qos/
+D: HTB qdisc and random networking hacks
+
 N: Alex deVries
 E: adevries@thepuffingroup.com
 D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux.
@@ -1258,7 +1263,7 @@
 S: Germany
 
 N: David Hinds
-E: dhinds@zen.stanford.edu
+E: dahinds@users.sourceforge.net
 W: http://tao.stanford.edu/~dhinds
 D: PCMCIA and CardBus stuff, PCMCIA-HOWTO, PCMCIA client drivers
 S: 2019 W. Middlefield Rd #1
@@ -1329,6 +1334,12 @@
 S: Provo, Utah 84606-5607
 S: USA
 
+N: Marcel Holtmann
+E: marcel@holtmann.org
+W: http://www.holtmann.org
+D: Author of the Linux Bluetooth Subsystem PC Card drivers
+S: Germany
+
 N: Rob W. W. Hooft
 E: hooft@EMBL-Heidelberg.DE
 D: Shared libs for graphics-tools and for the f2c compiler
@@ -2154,7 +2165,7 @@
 S: South Australia
 
 N. Wolfgang Muees
-E: wmues@nexgo.de
+E: wolfgang@iksw-muees.de
 D: Auerswald USB driver
 
 N: Ian A. Murdock
@@ -2335,8 +2346,8 @@
 D: modularized BSD Unix domain sockets
 
 N: Martin Kasper Petersen
-E: mkp@linuxcare.com
 E: mkp@mkp.net
+D: forte FM801 audio driver
 D: PA-RISC port
 D: XFS file system
 D: kiobuf based block I/O work
@@ -3311,14 +3322,10 @@
 S: Germany
 
 N: Leonard N. Zubkoff
-E: lnz@dandelion.com
 W: http://www.dandelion.com/Linux/
 D: BusLogic SCSI driver
 D: Mylex DAC960 PCI RAID driver
 D: Miscellaneous kernel fixes
-S: 3078 Sulphur Spring Court
-S: San Jose, California 95148
-S: USA
 
 N: Alessandro Zummo
 E: azummo@ita.flashnet.it
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bk-kernel-howto.txt linux-bk/Documentation/BK-usage/bk-kernel-howto.txt
--- linux-2.4.19/Documentation/BK-usage/bk-kernel-howto.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/bk-kernel-howto.txt	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bk-make-sum linux-bk/Documentation/BK-usage/bk-make-sum
--- linux-2.4.19/Documentation/BK-usage/bk-make-sum	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/bk-make-sum	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bksend linux-bk/Documentation/BK-usage/bksend
--- linux-2.4.19/Documentation/BK-usage/bksend	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/bksend	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/bz64wrap linux-bk/Documentation/BK-usage/bz64wrap
--- linux-2.4.19/Documentation/BK-usage/bz64wrap	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/bz64wrap	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/cset-to-linus linux-bk/Documentation/BK-usage/cset-to-linus
--- linux-2.4.19/Documentation/BK-usage/cset-to-linus	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/cset-to-linus	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/csets-to-patches linux-bk/Documentation/BK-usage/csets-to-patches
--- linux-2.4.19/Documentation/BK-usage/csets-to-patches	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/csets-to-patches	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/BK-usage/unbz64wrap linux-bk/Documentation/BK-usage/unbz64wrap
--- linux-2.4.19/Documentation/BK-usage/unbz64wrap	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/BK-usage/unbz64wrap	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/Changes linux-bk/Documentation/Changes
--- linux-2.4.19/Documentation/Changes	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/Changes	2002-11-22 15:35:33.000000000 +0000
@@ -55,7 +55,7 @@
 o  modutils               2.4.2                   # insmod -V
 o  e2fsprogs              1.25                    # tune2fs
 o  jfsutils               1.0.12                  # fsck.jfs -V
-o  reiserfsprogs          3.x.1b                  # reiserfsck 2>&1|grep reiserfsprogs
+o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
@@ -225,7 +225,6 @@
 version v0.99.0 or higher. Running old versions may cause problems
 with programs using shared memory.
 
-
 Networking
 ==========
 
@@ -326,7 +325,7 @@
 
 Reiserfsprogs
 -------------
-o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
+o  <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz>
 
 LVM toolset
 -----------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/Configure.help linux-bk/Documentation/Configure.help
--- linux-2.4.19/Documentation/Configure.help	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/Configure.help	2002-11-22 15:35:33.000000000 +0000
@@ -2,10 +2,7 @@
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
 #
-# Version 3.00: current with 2.4.19
-#
-# This version of the Linux kernel configuration help texts
-# corresponds to kernel versions 2.4.x and 2.5.x.
+# Version 3.01: current with 2.4.19+
 #
 # Translations of this file available on the WWW:
 #
@@ -233,6 +230,22 @@
   network and embedded applications.  For more information see the
   Axis Communication site, <http://developer.axis.com/>.
 
+Unsynced TSC support
+CONFIG_X86_TSC_DISABLE
+  This option is used for getting Linux to run on a NUMA multi-node 
+  boxes, laptops and other systems suffering from unsynced TSCs or 
+  TSC drift, which can cause gettimeofday to return non-monotonic values. 
+  Choosing this option will disable the CONFIG_X86_TSC optimization,
+  and allows you to then specify "notsc" as a boot option regardless of 
+  which processor you have compiled for. 
+  
+  NOTE: If your system hangs when init should run, you are probably
+  using a i686 compiled glibc which reads the TSC without checking for 
+  availability. Boot without "notsc" and install a i386 compiled glibc 
+  to solve the problem.
+
+  If unsure, say N.
+
 Multiquad support for NUMA systems
 CONFIG_MULTIQUAD
   This option is used for getting Linux to run on a (IBM/Sequent) NUMA 
@@ -376,6 +389,12 @@
   Select this if you have a 32-bit processor and more than 4
   gigabytes of physical RAM.
 
+HIGHMEM I/O support
+CONFIG_HIGHIO
+  If you want to be able to do I/O to high memory pages, say Y.
+  Otherwise low memory pages are used as bounce buffers causing a
+  degrade in performance.
+
 Normal floppy disk support
 CONFIG_BLK_DEV_FD
   If you want to use the floppy disk drive(s) of your PC under Linux,
@@ -494,7 +513,7 @@
 CONFIG_BLK_DEV_UMEM
   Saying Y here will include support for the MM5415 family of
   battery backed (Non-volatile) RAM cards.
-  http://www.umem.com/
+  <http://www.umem.com/>
 
   The cards appear as block devices that can be partitioned into
   as many as 15 partitions.
@@ -534,6 +553,17 @@
 
   If unsure, say N.
 
+Per partition statistics in /proc/partitions
+CONFIG_BLK_STATS
+  If you say yes here, your kernel will keep statistical information
+  for every partition. The information includes things as numbers of
+  read and write accesses, the number of merged requests etc.
+
+  This is required for the full functionality of sar(8) and interesting
+  if you want to do performance tuning, by tweaking the elevator, e.g.
+
+  If unsure, say N.
+
 ATA/IDE/MFM/RLL support
 CONFIG_IDE
   If you say Y here, your kernel will be able to manage low cost mass
@@ -671,6 +701,12 @@
   Support for outboard IDE disks, tape drives, and CD-ROM drives
   connected through a  PCMCIA card.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ide-cs.o
+
 Include IDE/ATAPI CD-ROM support
 CONFIG_BLK_DEV_IDECD
   If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is
@@ -817,6 +853,12 @@
   If both this SCSI emulation and native ATAPI support are compiled
   into the kernel, the native support will be used.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ide-scsi.o
+
 Use the NOOP Elevator (WARNING)
 CONFIG_BLK_DEV_ELEVATOR_NOOP
   If you are using a raid class top-level driver above the ATA/IDE core,
@@ -1004,6 +1046,11 @@
   Please read the comments at the top of
   <file:drivers/scsi/3w-xxxx.c>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called 3w-xxxx.o.
+
 AEC62XX chipset support
 CONFIG_BLK_DEV_AEC62XX
   This driver adds up to 4 more EIDE devices sharing a single
@@ -1067,10 +1114,10 @@
   This effect can be also invoked by calling "idex=ata66"
   If unsure, say N.
 
-CMD64X chipset support
+CMD64X and CMD680 chipset support
 CONFIG_BLK_DEV_CMD64X
   Say Y here if you have an IDE controller which uses any of these
-  chipsets: CMD643, CMD646, or CMD648.
+  chipsets: CMD643, CMD646, CMD648, CMD649 or CMD680.
 
 CY82C693 chipset support
 CONFIG_BLK_DEV_CY82C693
@@ -1796,6 +1843,12 @@
   <http://www.tldp.org/docs.html#howto>. There you will also learn
   where to get the supporting user space utilities raidtools.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  md.o
+
   If unsure, say N.
 
 Linear (append) mode
@@ -1885,6 +1938,12 @@
   transparent failover to the backup path(s) happens if a IO errors
   arrives on the primary path.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  multipath.o
+
   If unsure, say N.
 
 Support for IDE Raid controllers
@@ -1899,6 +1958,12 @@
   has its own Raid drivers, which you should use if you need better
   performance.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ataraid.o
+
 Support Promise software RAID (Fasttrak(tm))
 CONFIG_BLK_DEV_ATARAID_PDC
   Say Y or M if you have a Promise Fasttrak (tm) Raid controller
@@ -2493,6 +2558,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+skb->pkt_type packet match support
+CONFIG_IP_NF_MATCH_PKTTYPE
+  This patch allows you to match packet in accrodance
+  to its "class", eg. BROADCAST, MULTICAST, ...
+  
+  Typical usage:
+  iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG
+  
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 MAC address match support
 CONFIG_IP_NF_MATCH_MAC
   MAC matching allows you to match packets based on the source
@@ -2543,6 +2619,28 @@
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `N'.
 
+DSCP match support
+CONFIG_IP_NF_MATCH_DSCP
+  This option adds a `DSCP' match, which allows you to match against
+  the IPv4 header DSCP field (DSCP codepoint).
+
+  The DSCP codepoint can have any value between 0x0 and 0x4f.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
+ECN match support
+CONFIG_IP_NF_MATCH_ECN
+  This option adds a `ECN' match, which allows you to match against
+  the IPv4 and TCP header ECN fields.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
 TOS match support
 CONFIG_IP_NF_MATCH_TOS
   TOS matching allows you to match packets based on the Type Of
@@ -2551,6 +2649,18 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+conntrack match support
+CONFIG_IP_NF_MATCH_CONNTRACK
+  This is a general conntrack match module, a superset of the state match.
+
+  It allows matching on additional conntrack information, which is
+  useful in complex configurations, such as NAT gateways with multiple
+  internet links or tunnels.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+
 Connection state match support
 CONFIG_IP_NF_MATCH_STATE
   Connection state matching allows you to match packets based on their
@@ -2610,7 +2720,7 @@
 
   Please note that you will need a recent version (>= 1.2.6a)
   of the iptables userspace program in order to use this feature.
-  See http://www.iptables.org/ for download instructions.
+  See <http://www.iptables.org/> for download instructions.
 
   If unsure, say 'N'.
 
@@ -2668,6 +2778,36 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+DSCP target support
+CONFIG_IP_NF_TARGET_DSCP
+  This option adds a `DSCP' target, which allows you to create rules in
+  the iptables mangle table. The selected packet has the DSCP field set
+  to the hex value provided on the command line; unlike the TOS target
+  which will only set the legal values within ip.h.
+
+  The DSCP field can be set to any value between 0x0 and 0x4f. It does
+  take into account that bits 6 and 7 are used by ECN.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
+ECN target support
+CONFIG_IP_NF_TARGET_ECN
+  This option adds a `ECN' target, which can be used in the iptables mangle
+  table.  
+
+  You can use this target to remove the ECN bits from the IPv4 header of
+  an IP packet.  This is particularly useful, if you need to work around
+  existing ECN blackholes on the internet, but don't want to disable
+  ECN support in general.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
+ 
+
 TOS target support
 CONFIG_IP_NF_TARGET_TOS
   This option adds a `TOS' target, which allows you to create rules in
@@ -2714,6 +2854,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Helper match support
+CONFIG_IP_NF_MATCH_HELPER
+  Helper matching allows you to match packets in dynamic connections
+  tracked by a conntrack-helper, ie. ip_conntrack_ftp
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `Y'.
+
 TCPMSS match support
 CONFIG_IP_NF_MATCH_TCPMSS
   This option adds a `tcpmss' match, which allows you to examine the
@@ -2731,7 +2879,7 @@
   which can only be viewed through syslog.
 
   The appropriate userspace logging daemon (ulogd) may be obtained from
-  http://www.gnumonks.org/projects/ulogd
+  <http://www.gnumonks.org/projects/ulogd>
 
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  If unsure, say `N'.
@@ -2766,6 +2914,15 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+EUI64 address check (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_EUI64
+  This module performs checking on the IPv6 source address
+  Compares the last 64 bits with the EUI64 (delivered
+  from the MAC address) address
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 MAC address match support
 CONFIG_IP6_NF_MATCH_MAC
   mac matching allows you to match packets based on the source
@@ -2774,6 +2931,14 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+length match support
+CONFIG_IP6_NF_MATCH_LENGTH
+  This option allows you to match the length of a packet against a
+  specific value or range of values.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 Netfilter MARK match support
 CONFIG_IP6_NF_MATCH_MARK
   Netfilter mark matching allows you to match packets based on the
@@ -3278,6 +3443,16 @@
   a module, say M here and read <file:Documentation/modules.txt>.
   If unsure, say N.
 
+CONFIG_SYNCLINK_CS
+  Enable support for the SyncLink PC Card serial adapter, running
+  asynchronous and HDLC communications up to 512Kbps. The port is
+  selectable for RS-232, V.35, RS-449, RS-530, and X.21
+
+  This driver may be built as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called synclinkmp.o.  If you want to do that, say M
+  here.
+
 ACP Modem (Mwave) support
 CONFIG_MWAVE
   The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
@@ -3511,6 +3686,16 @@
 
   When in doubt, say N.
 
+ACPI PCI Hotplug driver
+CONFIG_HOTPLUG_PCI_ACPI
+  Say Y here if you have a system that supports PCI Hotplug using
+  ACPI.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called acpiphp.o. If you want to compile it
+  as a module, say M here and read <file:Documentation/modules.txt>.
+
 MCA support
 CONFIG_MCA
   MicroChannel Architecture is found in some IBM PS/2 machines and
@@ -5007,6 +5192,12 @@
   Say Y here if you need PCMCIA support for your PC-style parallel
   ports. If unsure, say N.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  parport_cs.o
+
 Support foreign hardware
 CONFIG_PARPORT_OTHER
   Say Y here if you want to be able to load driver modules to support
@@ -5311,6 +5502,12 @@
   be inserted in and removed from the running kernel whenever you
   want). Most people won't need this and can say N.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ipip.o
+
 GRE tunnels over IP
 CONFIG_NET_IPGRE
   Tunneling means encapsulating data of one protocol type within
@@ -5323,6 +5520,12 @@
   tunneling" above). In addition, GRE allows multicast redistribution
   through the tunnel.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ip_gre.o
+
 Broadcast GRE over IP
 CONFIG_NET_IPGRE_BROADCAST
   One application of GRE/IP is to construct a broadcast WAN (Wide Area
@@ -5404,14 +5607,6 @@
 
   It is safe to say N here for now.
 
-# 2.5 tree only
-IPv6: routing messages via old netlink
-CONFIG_IPV6_NETLINK
-  You can say Y here to receive routing messages from the IPv6 code
-  through the old netlink interface. However, a better option is to
-  say Y to "Kernel/User network link driver" and to "Routing
-  messages" instead.
-
 Kernel httpd acceleration
 CONFIG_KHTTPD
   The kernel httpd acceleration daemon (kHTTPd) is a (limited) web
@@ -5653,6 +5848,12 @@
   This driver is experimental, which means that it may not work.
   See the file <file:Documentation/networking/ltpc.txt>.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ltpc.o
+
 COPS LocalTalk PC card support
 CONFIG_COPS
   This allows you to use COPS AppleTalk cards to connect to LocalTalk
@@ -5662,6 +5863,12 @@
   networking support, above.
   Please read the file <file:Documentation/networking/cops.txt>.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  cops.o
+
 Dayna firmware support
 CONFIG_COPS_DAYNA
   Support COPS compatible cards with Dayna style firmware (Dayna
@@ -5810,6 +6017,11 @@
   useful if some other computer on your local network has a direct
   amateur radio connection.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called bpqether.o.
+
 High-speed (DMA) SCC driver for AX.25
 CONFIG_DMASCC
   This is a driver for high-speed SCC boards, i.e. those supporting
@@ -5874,9 +6086,10 @@
   port and includes some of the functions of a Terminal Node
   Controller. If you have one of those, say Y here.
 
-  If you want to compile this as a module ( = code which can be
+  If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
-  say M here and read <file:Documentation/modules.txt>.
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called yam.o.
 
 BAYCOM picpar and par96 driver for AX.25
 CONFIG_BAYCOM_PAR
@@ -6166,34 +6379,6 @@
 
   If unsure, say N.
 
-# 2.5 tree only
-Kernel/User network link driver
-CONFIG_NETLINK
-  This driver allows for two-way communication between the kernel and
-  user processes.  It does so by creating a new socket family,
-  PF_NETLINK.  Over this socket, the kernel can send and receive
-  datagrams carrying information.  It is documented on many systems in
-  netlink(7).
-
-  So far, the kernel uses this feature to publish some network related
-  information if you say Y to "Routing messages", below. You also need
-  to say Y here if you want to use arpd, a daemon that helps keep the
-  internal ARP cache (a mapping between IP addresses and hardware
-  addresses on the local network) small.  The ethertap device, which
-  lets user space programs read and write raw Ethernet frames, also
-  needs the network link driver.
-
-  If unsure, say Y.
-
-# 2.5 tree only
-Routing messages
-CONFIG_RTNETLINK
-  If you say Y here, user space programs can receive some network
-  related routing information over the netlink. 'rtmon', supplied
-  with the iproute2 package (<ftp://ftp.inr.ac.ru/>), can read and
-  interpret this data.  Information sent to the kernel over this link
-  is ignored.
-
 Netlink device emulation
 CONFIG_NETLINK_DEV
   This option will be removed soon. Any programs that want to use
@@ -6202,6 +6387,12 @@
   the real netlink socket.
   This is a backward compatibility option, choose Y for now.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  netlink_dev.o
+
 Asynchronous Transfer Mode (ATM)
 CONFIG_ATM
   ATM is a high-speed networking technology for Local Area Networks
@@ -6540,6 +6731,12 @@
   boards supported by this driver, and for further information
   on the use of this driver.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  cciss.o
+
 SCSI tape drive support for Smart Array 5xxx
 CONFIG_CISS_SCSI_TAPE
   When enabled (Y), this option allows SCSI tape drives and SCSI medium
@@ -7048,6 +7245,11 @@
   intended to replace the previous aic7xxx driver maintained by Doug
   Ledford since Doug is no longer maintaining that driver.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called aic7xxx.o.
+
 Adaptec I2O RAID support
 CONFIG_SCSI_DPT_I2O
   This driver supports all of Adaptec's I2O based RAID controllers as 
@@ -7244,6 +7446,11 @@
   Say Y here to compile in support for the Compaq StorageWorks Fibre
   Channel 64-bit/66Mhz Host Bus Adapter.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called cpqfc.o.
+
 DMX3191D SCSI support
 CONFIG_SCSI_DMX3191D
   This is support for Domex DMX3191D SCSI Host Adapters.
@@ -7401,6 +7608,11 @@
   Unless you have an NCR manufactured machine, the chances are that
   you do not have this SCSI card, so say N.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called NCR_D700.o.
+
 HP LASI SCSI support for 53c700/710
 CONFIG_SCSI_LASI700
   This is a driver for the lasi baseboard in some parisc machines
@@ -7469,6 +7681,11 @@
   Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sym53c8xx.o.
+
 PCI DMA addressing mode
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
   This option only applies to PCI-SCSI chip that are PCI DAC capable 
@@ -7531,6 +7748,11 @@
   Please read <file:drivers/scsi/README.ncr53c8xx> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ncr53c8xx.o.
+
 SYM53C8XX Version 1 SCSI support
 CONFIG_SCSI_SYM53C8XX
   This driver supports all the features of recent 53C8XX chips (used
@@ -7556,6 +7778,11 @@
   Please read <file:drivers/scsi/README.ncr53c8xx> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sym53c8xx.o.
+
 Synchronous transfer frequency in MHz
 CONFIG_SCSI_NCR53C8XX_SYNC
   The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
@@ -8128,10 +8355,10 @@
   in the kernel source in <file:drivers/scsi/gdth.c> and
   <file:drivers/scsi/gdth.h.>
 
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  If you want to compile it as a module, say M here and read
-  <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called gdth.o.
 
 IOMEGA parallel port (ppa - older drives)
 CONFIG_SCSI_PPA
@@ -8221,6 +8448,11 @@
   important data. This is primarily of use to people trying to debug
   the middle and upper layers of the SCSI subsystem. If unsure, say N.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called scsi_debug.o.
+
 Fibre Channel and FC4 SCSI support
 CONFIG_FC4
   Fibre Channel is a high speed serial protocol mainly used to
@@ -8648,9 +8880,10 @@
   a modem (not a synchronous or ISDN modem) to contact your ISP, you
   need this option.
 
-  This code is also available as a module (code which can be inserted
-  into and removed from the running kernel).  If you want to compile
-  it as a module, say M here and read <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ppp_async.o.
 
   If unsure, say Y.
 
@@ -8660,10 +8893,10 @@
   (HDLC) tty devices, such as the SyncLink adapter. These devices
   are often used for high-speed leased lines like T1/E1.
 
-  This code is also available as a module (code which can be inserted
-  into and removed from the running kernel).  If you want to compile
-  it as a module, say M here and read
-  <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ppp_synctty.o.
 
 PPP Deflate compression
 CONFIG_PPP_DEFLATE
@@ -8674,10 +8907,10 @@
   Deflate compression method as well for this to be useful.  Even if
   they don't support it, it is safe to say Y here.
 
-  This code is also available as a module (code which can be inserted
-  into and removed from the running kernel).  If you want to compile
-  it as a module, say M here and read
-  <file:Documentation/modules.txt>.
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ppp_deflate.o.
 
 PPP BSD-Compress compression
 CONFIG_PPP_BSDCOMP
@@ -9096,6 +9329,11 @@
   configure your card and that /etc/pcmcia/wireless.opts works :
   <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hermes.o.
+
 Hermes 802.11b in PLX9052 based PCI adaptor support
 CONFIG_PLX_HERMES
   Enable support for PCMCIA cards supported by the "Hermes" (aka
@@ -9134,6 +9372,11 @@
   configure your card and that /etc/pcmcia/wireless.opts works:
   <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called orinoco_cs.o.
+
 Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards
 CONFIG_AIRO
   This is the standard Linux driver to support Cisco/Aironet ISA and
@@ -9168,6 +9411,11 @@
   for location).  You also want to check out the PCMCIA-HOWTO,
   available from <http://www.tldp.org/docs.html#howto>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called airo_cs.o.
+
 Aviator/Raytheon 2.4MHz wireless support
 CONFIG_PCMCIA_RAYCS
   Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
@@ -9353,6 +9601,11 @@
   of the Cisco HDLC/PPP driver (syncppp.c).
   The SyncLink WAN driver (in character devices) must also be enabled.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called syncppp.o.
+
 FarSync T-Series X.21 (and V.35/V.24) cards
 CONFIG_FARSYNC
   This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
@@ -9558,6 +9811,20 @@
   whenever you want).  If you want to compile it as a module, say M
   here and read <file:Documentation/modules.txt>.
 
+CONFIG_NET_SCH_HTB
+  Say Y here if you want to use the Hierarchical Token Buckets (HTB)
+  packet scheduling algorithm for some of your network devices. See
+  URL <http://luxik.cdi.cz/~devik/qos/htb/> for complete manual and
+  in-depth articles.
+
+  HTB is very similar to the CBQ regarding its goals however is has 
+  different properties and different algorithm.
+
+  This code is also available as a module called sch_htb.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want).  If you want to compile it as a module, say M
+  here and read <file:Documentation/modules.txt>.
+
 CSZ packet scheduler
 CONFIG_NET_SCH_CSZ
   Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet
@@ -9839,6 +10106,11 @@
 
   At this point, the driver can only be compiled as a module.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hostess_sv11.o.
+
 COSA/SRP sync serial board support
 CONFIG_COSA
   This is a driver for COSA and SRP synchronous serial boards. These
@@ -10133,7 +10405,7 @@
 
   Read linux/Documentation/networking/slicecom.txt for help on
   configuring and using SliceCOM interfaces. Further info on these cards
-  can be found at http://www.itc.hu or <info@itc.hu>.
+  can be found at <http://www.itc.hu> or <info@itc.hu>.
 
 Support for HDLC and syncPPP protocols on MultiGate boards
 CONFIG_COMX_PROTO_PPP
@@ -10207,6 +10479,11 @@
   Generic HDLC driver currently supports raw HDLC, Cisco HDLC, Frame
   Relay, synchronous Point-to-Point Protocol (PPP) and X.25.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hdlc.o.
+
   If unsure, say N here.
 
 Raw HDLC support
@@ -10259,6 +10536,11 @@
 
   Note that N2csu and N2dds cards are not supported by this driver.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called n2.o.
+
   If unsure, say N here.
 
 Moxa C101 support
@@ -10267,6 +10549,11 @@
   Technologies Co., Ltd. If you have such a card,
   say Y here and see <http://hq.pm.waw.pl/pub/hdlc/>
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called c101.o.
+
   If unsure, say N here.
 
 Ethernet (10 or 100Mbit)
@@ -10474,12 +10761,14 @@
   in case your mainboard has memory consistency issues.  If unsure,
   say N.
 
-Support for automatic channel equalization
+Support for uncommon RTL-8139 rev. K (automatic channel equalization)
 CONFIG_8139TOO_TUNE_TWISTER
-  This implements a function which might come in handy in case you are
-  using low quality on long cabling. It tries to match the transceiver
-  to the cable characteristics. This is experimental since hardly
-  documented by the manufacturer.  If unsure, say N.
+  This implements a function which might come in handy in case you
+  are using low quality on long cabling. It is required for RealTek
+  RTL-8139 revision K boards, and totally unused otherwise.  It tries
+  to match the transceiver to the cable characteristics. This is
+  experimental since hardly documented by the manufacturer.
+  If unsure, say Y.
 
 Support for older RTL-8129/8130 boards
 CONFIG_8139TOO_8129
@@ -10488,6 +10777,14 @@
   instead of an internal one.  Disabling this option will save some
   memory by making the code size smaller.  If unsure, say Y.
 
+Use older RX-reset method
+CONFIG_8139_OLD_RX_RESET
+  The 8139too driver was recently updated to contain a more rapid
+  reset sequence, in the face of severe receive errors.  This "new"
+  RX-reset method should be adequate for all boards.  But if you
+  experience problems, you can enable this option to restore the
+  old RX-reset behavior.  If unsure, say N.
+
 SiS 900/7016 PCI Fast Ethernet Adapter support
 CONFIG_SIS900
   This is a driver for the Fast Ethernet PCI network cards based on
@@ -10609,6 +10906,16 @@
   Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
   <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
 
+  This chip is also used by Apple under the name GMAC in all their recent
+  machines starting with the first iBook. This includes all AGP capable
+  Apple machines except some early G4s and iMacs that still used a
+  Tulip chip. This driver obsoletes the GMAC driver for these machines.
+  
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sungem.o.
+
 Broadcom Tigon3 support
 CONFIG_TIGON3
   This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
@@ -10639,6 +10946,123 @@
   say M here and read <file:Documentation/modules.txt>.  This is
   recommended.  The module will be called dl2k.o.
 
+EtherExpress Pro/100 support (e100, Alternate Intel driver)
+CONFIG_E100
+  This driver supports Intel(R) PRO/100 family of adapters, which
+  includes:
+
+     Controller  Adapter Name                       Board IDs
+     ----------  ------------                       ---------
+
+     82558       PRO/100+ PCI Adapter               668081-xxx,
+                                                    689661-xxx
+     82558       PRO/100+ Management Adapter        691334-xxx,
+                                                    701738-xxx,
+                                                    721383-xxx
+     82558       PRO/100+ Dual Port Server Adapter  714303-xxx,
+                                                    711269-xxx,
+                                                    A28276-xxx
+     82558       PRO/100+ PCI Server Adapter        710550-xxx
+     82550       PRO/100 S Server Adapter           752438-xxx
+     82559                                          A56831-xxx,
+                                                    A10563-xxx,
+                                                    A12171-xxx,
+                                                    A12321-xxx,
+                                                    A12320-xxx,
+                                                    A12170-xxx
+                                                    748568-xxx
+                                                    748565-xxx
+     82550       PRO/100 S Desktop Adapter          751767-xxx
+     82559                                          748592-xxx,
+                                                    A12167-xxx,
+                                                    A12318-xxx,
+                                                    A12317-xxx,
+                                                    A12165-xxx,
+                                                    748569-xxx
+     82559       PRO/100+ Server Adapter            729757-xxx
+     82559       PRO/100 S Management Adapter       748566-xxx,
+                                                    748564-xxx
+     82550       PRO/100 S Dual Port Server Adapter A56831-xxx
+     82551       PRO/100 M Desktop Adapter          A80897-xxx
+                 PRO/100 S Advanced Management Adapter
+                                                    747842-xxx,
+                                                    745171-xxx
+     CNR         PRO/100 VE Desktop Adapter         A10386-xxx,
+                                                    A10725-xxx,
+                                                    A23801-xxx,
+                                                    A19716-xxx
+                 PRO/100 VM Desktop Adapter         A14323-xxx,
+                                                    A19725-xxx,
+                                                    A23801-xxx,
+                                                    A22220-xxx,
+                                                    A23796-xxx
+
+
+  To verify that your adapter is supported, find the board ID number
+  on the adapter. Look for a label that has a barcode and a number
+  in the format 123456-001 (six digits hyphen three digits). Match
+  this to the list of numbers above.
+
+  For more information on how to identify your adapter, go to the
+  Adapter & Driver ID Guide at:
+
+    http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+  For the latest Intel PRO/100 network driver for Linux, see:
+
+    http://appsr.intel.com/scripts-df/support_intel.asp
+
+  More specific information on configuring the driver is in
+  <file:Documentation/networking/e100.txt>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called e100.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt> as well
+  as <file:Documentation/networking/net-modules.txt>.
+
+Intel(R) PRO/1000 Gigabit Ethernet support
+CONFIG_E1000
+  This driver supports Intel(R) PRO/1000 gigabit ethernet family of
+  adapters, which includes:
+
+     Controller  Adapter Name                         Board IDs
+     ----------  ------------                         ---------
+     82542       PRO/1000 Gigabit Server Adapter      700262-xxx,
+                                                      717037-xxx
+     82543       PRO/1000 F Server Adapter            738640-xxx,
+                                                      A38888-xxx
+     82543       PRO/1000 T Server Adapter            A19845-xxx,
+                                                      A33948-xxx
+     82544       PRO/1000 XT Server Adapter           A51580-xxx
+     82544       PRO/1000 XF Server Adapter           A50484-xxx
+     82544       PRO/1000 T Desktop Adapter           A62947-xxx
+     82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+     82545       PRO/1000 MT Server Adapter           A92165-xxx
+     82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
+     82545       PRO/1000 MF Server Adapter           A91622-xxx
+     82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
+     82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx 
+
+  For more information on how to identify your adapter, go to the
+  Adapter & Driver ID Guide at:
+
+   <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+  For general information and support, go to the Intel support
+  website at:
+
+   <http://support.intel.com>
+
+  More specific information on configuring the driver is in 
+  <file:Documentation/networking/e1000.txt>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called e1000.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt> as well
+  as <file:Documentation/networking/net-modules.txt>.
+
 AMD LANCE and PCnet (AT1500 and NE2100) support
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
@@ -10798,10 +11222,10 @@
   <file:Documentation/networking/vortex.txt> and in the comments at
   the beginning of <file:drivers/net/3c59x.c>.
 
-  If you want to compile this as a module ( = code which can be
+  If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
-  say M here and read <file:Documentation/modules.txt> as well as
-  <file:Documentation/networking/net-modules.txt>.
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called 3c59x.o.
 
 Other ISA cards
 CONFIG_NET_ISA
@@ -10852,6 +11276,11 @@
   documentation in <file:Documentation/networking/arcnet.txt> for more
   information about using arc0e and arc0s.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called rfc1051.o.
+
 Enable standard ARCNet packet format (RFC 1201)
 CONFIG_ARCNET_1201
   This allows you to use RFC1201 with your ARCnet card via the virtual
@@ -10861,12 +11290,22 @@
   ARCnet documentation in <file:Documentation/networking/arcnet.txt>
   for more information about using arc0.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called rfc1201.o.
+
 Enable raw mode packet interface
 CONFIG_ARCNET_RAW
   ARCnet "raw mode" packet encapsulation, no soft headers.  Unlikely
   to work unless talking to a copy of the same Linux arcnet driver,
   but perhaps marginally faster in that case.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called arc-rawmode.o.
+
 ARCnet COM90xx (normal) chipset driver
 CONFIG_ARCNET_COM90xx
   This is the chipset driver for the standard COM90xx cards. If you
@@ -11115,6 +11554,11 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/natsemi.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called natsemi.o.
+
 NatSemi workaround for high errors
 CONFIG_NATSEMI_CABLE_MAGIC
   Some systems see lots of errors with NatSemi ethernet controllers
@@ -11171,6 +11615,11 @@
   boards with this driver should be possible, but has not been tested
   up to now due to lack of hardware.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ibmlana.o.
+
 EISA, VLB, PCI and on board controllers
 CONFIG_NET_PCI
   This is another class of network cards which attach directly to the
@@ -11340,12 +11789,22 @@
   cards. Specifications and data at
   <http://www.myson.com.hk/mtd/datasheet/>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called fealnx.o.
+
 LP486E on board Ethernet
 CONFIG_LP486E
   Say Y here to support the 82596-based on-board Ethernet controller
   for the Panther motherboard, which is one of the two shipped in the
   Intel Professional Workstation.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called lp486e.o.
+
 ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
@@ -11431,6 +11890,11 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/epic100.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called epic100.o.
+
 DEC LANCE Ethernet controller support
 CONFIG_DECLANCE
   This driver is for the series of Ethernet controllers produced by
@@ -11448,6 +11912,19 @@
   More specific information and updates are available from
   <http://www.scyld.com/network/sundance.html>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sundance.o.
+
+Sundance Alta memory-mapped I/O support
+CONFIG_SUNDANCE_MMIO
+  Enable memory-mapped I/O for interaction with Sundance NIC registers.
+  Do NOT enable this by default, PIO (enabled when MMIO is disabled)
+  is known to solve bugs on certain chips.
+
+  If unsure, say N.
+
 Sun3/Sun3x on-board LANCE support
 CONFIG_SUN3LANCE
   Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
@@ -11795,6 +12272,11 @@
   This is support for the DIGITAL series of EISA (DEFEA) and PCI
   (DEFPA) controllers which can connect you to a local FDDI network.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called defxx.o.
+
 SysKonnect FDDI PCI support
 CONFIG_SKFP
   Say Y here if you have a SysKonnect FDDI PCI adapter.
@@ -12181,6 +12663,12 @@
   them. It will also allow you to select individual drivers for 
   particular hardware and users of MTD devices. If unsure, say N.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  mtdcore.o
+
 MTD debugging support
 CONFIG_MTD_DEBUG
   This turns on low-level debugging for the entire MTD sub-system.
@@ -12193,6 +12681,12 @@
   a separate MTD device, you require this option to be enabled. If
   unsure, say 'Y'.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  mtdpart.o
+
   Note, however, that you don't need this option for the DiskOnChip
   devices. Partitioning on NFTL 'devices' is a different - that's the
   'normal' form of partitioning used on a block device.
@@ -12213,6 +12707,12 @@
   SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
   example.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  redboot.o
+
 Compaq bootldr partition table parsing
 CONFIG_MTD_BOOTLDR_PARTS
   The Compaq bootldr deals with multiple 'images' in flash devices
@@ -12254,6 +12754,12 @@
   memory chips, and also use ioctl() to obtain information about
   the device, or to erase parts of it.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  mtdchar.o
+
 Caching block device access to MTD devices
 CONFIG_MTD_BLOCK
   Although most flash chips have an erase size too large to be useful
@@ -12274,6 +12780,12 @@
   You do not need this option for use with the DiskOnChip devices. For
   those, enable NFTL support (CONFIG_NFTL) instead.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  mtdblock.o
+
 Readonly block device access to MTD devices
 CONFIG_MTD_BLOCK_RO
   This allows you to mount read-only file systems (such as cramfs)
@@ -12283,6 +12795,12 @@
   You do not need this option for use with the DiskOnChip devices. For
   those, enable NFTL support (CONFIG_NFTL) instead.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  mtdblock_ro.o
+
 FTL (Flash Translation Layer) support
 CONFIG_FTL
   This provides support for the original Flash Translation Layer which
@@ -12297,6 +12815,12 @@
   permitted to copy, modify and distribute the code as you wish. Just
   not use it.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  ftl.o
+
 NFTL (NAND Flash Translation Layer) support
 CONFIG_NFTL
   This provides support for the NAND Flash Translation Layer which is
@@ -12311,6 +12835,12 @@
   permitted to copy, modify and distribute the code as you wish. Just
   not use it.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  nftl.o
+
 Write support for NFTL (EXPERIMENTAL)
 CONFIG_NFTL_RW
   If you're lucky, this will actually work. Don't whinge if it
@@ -12327,6 +12857,12 @@
   option. Visit <http://www.amd.com/products/nvd/overview/cfi.html>
   for more information on CFI.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  cfi_probe.o
+
 CFI Advanced configuration options
 CONFIG_MTD_CFI_ADV_OPTIONS
   If you need to specify a specific endianness for access to flash
@@ -12419,6 +12955,12 @@
   commands, including some which are not CFI-compatible and hence 
   cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  sharp.o
+
 AMD compatible flash chip support (non-CFI)
 CONFIG_MTD_AMDSTD
   This option enables support for flash chips using AMD-compatible
@@ -12427,16 +12969,34 @@
 
   It also works on AMD compatible chips that do conform to CFI.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  amd_flash.o
+
 Support for RAM chips in bus mapping
 CONFIG_MTD_RAM
   This option enables basic support for RAM chips accessed through 
   a bus mapping driver.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  map_ram.o
+
 Support for ROM chips in bus mapping
 CONFIG_MTD_ROM
   This option enables basic support for ROM chips accessed through 
   a bus mapping driver.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  map_rom.o
+
 JEDEC device support
 CONFIG_MTD_JEDEC
   Enable older older JEDEC flash interface devices for self
@@ -12446,6 +13006,12 @@
   chips. WARNING!!!! This code does not compile and is incomplete as
   are the specific JEDEC devices drivers.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  jedec.o
+
 CFI Flash device mapped on StrongARM SA11x0
 CONFIG_MTD_SA1100
   This enables access to the flash chips on most platforms based on
@@ -12476,6 +13042,12 @@
   configure the physical address and size of the flash chips on
   your particular board as well as the bus width.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  physmap.o
+
 Physical start location of flash chip mapping
 CONFIG_MTD_PHYSMAP_START
   This is the physical memory location at which the flash chips
@@ -12529,6 +13101,12 @@
   Dual-in-line JEDEC chip. This 'mapping' driver supports that
   arrangement, implementing three MTD devices.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  sc520cdp.o
+
 Flash chip mapping on Arcom Control Systems SBC-MediaGX
 CONFIG_MTD_SBC_GXX
   This provides a driver for the on-board flash of Arcom Control
@@ -12626,6 +13204,12 @@
   Computer. More information on the board is available at
   <http://www.octagonsystems.com/Products/5066/5066.html>.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  octagon-5066.o
+
 JEDEC Flash device mapped on Tempustech VMAX SBC301
 CONFIG_MTD_VMAX
   This provides a 'mapping' driver which supports the way in which
@@ -12633,11 +13217,23 @@
   Board Computer. More information on the board is available at
   <http://www.tempustech.com/tt301.htm>.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  vmax301.o
+
 Support for NAND flash devices
 CONFIG_MTD_NAND
   This enables support for accessing all type of NAND flash
   devices.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  nand.o
+
 Support for software ECC algorithm
 CONFIG_MTD_NAND_ECC
   This enables software-based ECC for use with NAND flash chips. It
@@ -12663,6 +13259,12 @@
   This provides an MTD device driver for the M-Systems DiskOnChip
   1000 devices, which are obsolete so you probably want to say 'N'.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  doc1000.o
+
 M-Systems Disk-On-Chip 2000 and Millennium support
 CONFIG_MTD_DOC2000
   This provides an MTD device driver for the M-Systems DiskOnChip
@@ -12678,6 +13280,12 @@
   emulate a block device by using a kind of file system on the flash
   chips.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  doc2000.o
+
 Alternative Disk-On-Chip Millennium support
 CONFIG_MTD_DOC2001
   This provides an alternative MTD device driver for the M-Systems 
@@ -12692,6 +13300,12 @@
   emulate a block device by using a kind of file system on the flash
   chips.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  doc2001.o
+
 Probe for DiskOnChip devices
 CONFIG_MTD_DOCPROBE
   This isn't a real config option, it's derived.
@@ -12751,6 +13365,12 @@
   particularly useful on the 2.2 kernels on PPC architectures as there
   was limited kernel space to deal with.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  pmc551.o
+
 PMC551 256M DRAM Bugfix
 CONFIG_MTD_PMC551_BUGFIX
   Some of Ramix's PMC551 boards with 256M configurations have invalid
@@ -12769,12 +13389,24 @@
   you can still use it for storage or swap by using this driver to
   present it to the system as a Memory Technology Device.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  slram.o
+
 Debugging RAM test driver
 CONFIG_MTD_MTDRAM
   This enables a test MTD device driver which uses vmalloc() to
   provide storage.  You probably want to say 'N' unless you're
   testing stuff.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  mtdram.o
+
 MTDRAM erase block size in KB
 CONFIG_MTDRAM_ERASE_SIZE
   This allows you to configure the size of the erase blocks in the
@@ -12817,6 +13449,12 @@
   the system regardless of media presence.  Device nodes created
   with this driver will return -ENODEV upon access.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  map_absent.o
+
 MTD emulation using block device
 CONFIG_MTD_BLKMTD
   This driver allows a block device to appear as an MTD. It would
@@ -12827,6 +13465,12 @@
     Testing MTD users (eg JFFS2) on large media and media that might
     be removed during a write (using the floppy drive).
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  blkmtd.o
+
 Cirrus CDB89712 evaluation board mappings
 CONFIG_MTD_CDB89712
   This enables access to the flash or ROM chips on the CDB89712 board.
@@ -12844,6 +13488,12 @@
   non-CFI Intel chips (that code is in MTD CVS and should shortly be sent
   for inclusion in Linus' tree)
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  jedec_probe.o
+
 BIOS flash chip on Intel L440GX boards
 CONFIG_MTD_L440GX
   Support for treating the BIOS flash chip on Intel L440GX motherboards
@@ -12851,6 +13501,12 @@
 
   BE VERY CAREFUL.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  l440gx.o
+
 28F160xx flash driver for LART
 CONFIG_MTD_LART
   This enables the flash driver for LART. Please note that you do
@@ -13108,9 +13764,9 @@
   The module will be called wacom.o.  If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Aiptek 8000U tablet support
+Aiptek 6000U/8000U tablet support
 CONFIG_USB_AIPTEK
-  Say Y here if you want to use the USB version of the Aiptek 8000U
+  Say Y here if you want to use the USB version of the Aiptek 6000U/8000U
   tablet.  Make sure to say Y to "Event interface support"
   (CONFIG_INPUT_EVDEV) as well.
 
@@ -13242,7 +13898,6 @@
   inserted in and removed from the running kernel whenever you want).
   The module will be called audio.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
-			
 
 USB Modem (CDC ACM) support
 CONFIG_USB_ACM
@@ -13418,6 +14073,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.
@@ -13710,7 +14373,7 @@
 CONFIG_USB_RTL8150
   Say Y here if you have RTL8150 based usb-ethernet adapter.
   Send me (petkan@users.sourceforge.net) any comments you may have.
-  You can also check for updates at http://pegasus2.sourceforge.net/
+  You can also check for updates at <http://pegasus2.sourceforge.net/>
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -13761,6 +14424,7 @@
 CONFIG_USB_CATC
   Say Y if you want to use one of the following 10Mbps USB Ethernet
   device based on the EL1210A chip. Supported devices are:
+    Belkin F5U011
     Belkin F5U111
     CATC NetMate
     CATC NetMate II
@@ -13940,6 +14604,11 @@
   Say Y here to include additional code to support the Sandisk SDDR-09
   SmartMedia reader in the USB Mass Storage driver.
 
+SanDisk SDDR-55 SmartMedia support
+CONFIG_USB_STORAGE_SDDR55
+  Say Y here to include additional code to support the Sandisk SDDR-55
+  SmartMedia reader in the USB Mass Storage driver.
+
 USB Diamond Rio500 support
 CONFIG_USB_RIO500
   Say Y here if you want to connect a USB Rio500 mp3 player to your
@@ -13949,7 +14618,7 @@
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called rio500.o. If you want to compile it as
-  a module, say M here and read <file:Documentation/modules.txt>.
+  a module, say M here and read <file:Documenatation/modules.txt>.
 
 USB Auerswald ISDN device support
 CONFIG_USB_AUERSWALD
@@ -13959,7 +14628,26 @@
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
   The module will be called auerswald.o. If you want to compile it as
-  a module, say M here and read <file:Documentation/modules.txt>.
+  a module, say M here and read <file:Documenatation/modules.txt>
+
+CONFIG_USB_TIGL
+  If you own a Texas Instruments graphing calculator and use a 
+  TI-GRAPH LINK USB cable (aka SilverLink), then you might be 
+  interested in this driver.
+
+  If you enable this driver, you will be able to communicate with
+  your calculator through a set of device nodes under /dev.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called tiglusb.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+  If you don't know what the SilverLink cable is or what a Texas
+  Instruments graphing calculator is, then you probably don't need this
+  driver.
+
+  If unsure, say N.
 
 Tieman Voyager USB Braille display support
 CONFIG_USB_BRLVOYAGER
@@ -13972,6 +14660,18 @@
   The module will be called brlvger.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+USBLCD support
+CONFIG_USB_LCD
+  Say Y here if you want to connect an USBLCD to your computer's
+  USB port. The USBLCD is a small USB interface board for
+  alphanumeric LCD modules. See <http://www.usblcd.de> for more
+  information.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called usblcd.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
 D-Link DSB-R100 FM radio support
 CONFIG_USB_DSBR
   Say Y here if you want to connect this type of radio to your
@@ -14257,6 +14957,27 @@
   The module will be called bluetooth.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+USB MIDI support
+CONFIG_USB_MIDI
+  Say Y here if you want to connect a USB MIDI device to your
+  computer's USB port. This driver is for devices that comply with
+  'Universal Serial Bus Device Class Definition for MIDI Device'.
+
+  The following devices are known to work:
+    * Steinberg USB2MIDI
+    * Roland MPU64
+    * Roland PC-300
+    * Roland SC8850
+    * Roland UM-1
+    * Roland UM-2
+    * Roland UA-100
+    * Yamaha MU1000
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called usb-midi.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 Minix fs support
 CONFIG_MINIX_FS
   Minix is a simple operating system used in many classes about OS's.
@@ -14314,12 +15035,13 @@
 
 Publish some reiserfs-specific info under /proc/fs/reiserfs
 CONFIG_REISERFS_PROC_INFO
-  Create under /proc/fs/reiserfs hierarchy of files, displaying
-  various ReiserFS statistics and internal data on the expense of
-  making your kernel or module slightly larger (+8 KB).  This also
-  increases amount of kernel memory required for each mount.  Almost
-  everyone but ReiserFS developers and people fine-tuning reiserfs or
-  tracing problems should say N.
+  Create under /proc/fs/reiserfs a hierarchy of files, displaying
+  various ReiserFS statistics and internal data at the expense of making
+  your kernel or module slightly larger (+8 KB). This also increases the
+  amount of kernel memory required for each mount by 440 bytes.
+  It isn't useful to average persons, and you probably can't measure the
+  performance cost of it.  If you are fine-tuning reiserfs, say Y,
+  otherwise say N.
 
 Second extended fs support
 CONFIG_EXT2_FS
@@ -14441,6 +15163,35 @@
   Because this option adds considerably to the size of each buffer,
   most people will want to say N here.
 
+BeOS filesystem support (BeFS) (read only)
+CONFIG_BEFS_FS
+  The BeOS File System (BeFS) is the native file system of Be, Inc's
+  BeOS. Notable features include support for arbitrary attributes
+  on files and directories, and database-like indices on selected
+  attributes. (Also note that this driver doesn't make those features
+  available at this time). It is a 64 bit filesystem, so it supports
+  extremely large volumes and files.
+
+  If you use this filesystem, you should also say Y to at least one
+  of the NLS (native language support) options below.
+
+  If you don't know what this is about, say N.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called befs.o.
+
+Debug BeFS
+CONFIG_BEFS_DEBUG
+  If you say Y here, you can use the 'debug' mount option to enable
+  debugging output from the driver. This is unlike previous versions
+  of the driver, where enabling this option would turn on debugging
+  output automatically.
+
+  Example:
+  mount -t befs /dev/hda2 /mnt -o debug
+
 BFS file system support
 CONFIG_BFS_FS
   Boot File System (BFS) is a file system used under SCO UnixWare to
@@ -14884,13 +15635,10 @@
   If you would like to include the NFSv3 server as well as the NFSv2
   server, say Y here.  If unsure, say Y.
 
-Provide NFS over TCP server support DEVELOPER ONLY
+Provide NFS over TCP server support EXPERIMENTAL
 CONFIG_NFSD_TCP
-  If you are a developer and want to work on fixing problems with
-  NFS server over TCP support, say Y here.  If unsure, say N.
-
-  Some problems can be found by looking for FIXME in
-  <file:net/sunrpc/svcsock.c>.
+  Enable NFS service over TCP connections.  This the officially
+  still experimental, but seems to work well.
 
 OS/2 HPFS file system support
 CONFIG_HPFS_FS
@@ -15331,12 +16079,6 @@
   were partitioned using EFI GPT.  Presently only useful on the
   IA-64 platform.
 
-/dev/guid support (EXPERIMENTAL)
-CONFIG_DEVFS_GUID
-  Say Y here if you would like to access disks and partitions by
-  their Globally Unique Identifiers (GUIDs) which will appear as
-  symbolic links in /dev/guid.
-
 Ultrix partition table support
 CONFIG_ULTRIX_PARTITION
   Say Y here if you would like to be able to read the hard disk
@@ -15345,9 +16087,11 @@
 
 IBM disk label and partition support
 CONFIG_IBM_PARTITION
-  Say Y here if you would like to be able to read the hard disk
-  partition table format used by IBM DASD disks operating under CMS.
-  Otherwise, say N.
+  You have to say Y here if you would like to be able to read volume 
+  labels of IBM DASD disks. These can be ECKD DASD disks with 
+  compatible disk layout (cdl) and standard Linux disk layout (ldl), 
+  FBA DASD disks and CMS reserved minidisks.
+  Otherwise, say N and you will not be able to access these disks.
 
 ADFS file system support
 CONFIG_ADFS_FS
@@ -15375,6 +16119,25 @@
   hard drives and ADFS-formatted floppy disks. This is experimental
   codes, so if you're unsure, say N.
 
+JFS filesystem support
+CONFIG_JFS_FS
+  This is a port of IBM's Journalling Filesystem .  More information is
+  available in the file Documentation/filesystems/jfs.txt.
+
+  If you do not intend to use the JFS filesystem, say N.
+
+JFS Debugging
+CONFIG_JFS_DEBUG
+  If you are experiencing any problems with the JFS filesystem, say
+  Y here.  This will result in additional debugging messages to be
+  written to the system log.  Under normal circumstances, this
+  results in very little overhead.
+
+JFS Statistics
+CONFIG_JFS_STATISTICS
+  Enabling this option will cause statistics from the JFS file system
+  to be made available to the user in the /proc/fs/jfs/ directory.
+
 /dev/pts file system for Unix98 PTYs
 CONFIG_DEVPTS_FS
   You should say Y here if you said Y to "Unix98 PTY support" above.
@@ -16487,6 +17250,17 @@
   The module will be called synclink.o.  If you want to do that, say M
   here.
 
+CONFIG_SYNCLINKMP
+  Enable support for the SyncLink Multiport (2 or 4 ports)
+  serial adapter, running asynchronous and HDLC communications up
+  to 2.048Mbps. Each ports is independently selectable for
+  RS-232, V.35, RS-449, RS-530, and X.21
+
+  This driver may be built as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called synclinkmp.o.  If you want to do that, say M
+  here.
+
 Synchronous HDLC line discipline support
 CONFIG_N_HDLC
   Allows synchronous HDLC communications with tty device drivers that
@@ -17929,20 +18703,6 @@
   computer, say `Y' here to support its built-in watchdog timer
   feature.  See the help for CONFIG_WATCHDOG for discussion.
 
-W83877F Watchdog Timer
-CONFIG_W83877F_WDT
-  This is the driver for the hardware watchdog on the W83877F chipset
-  as used in EMACS PC-104 motherboards (and likely others).  This
-  watchdog simply watches your kernel to make sure it doesn't freeze,
-  and if it does, it reboots your computer after a certain amount of
-  time.
-
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  The module is called mixcomwd.o.  If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.  Most
-  people will say N.
-
 ALi M7101 Watchdog Timer
 CONFIG_ALIM7101_WDT
   This is the driver for the hardware watchdog on the ALi M7101 PMU
@@ -18007,11 +18767,11 @@
   module, say M here and read <file:Documentation/modules.txt>.  Most
   people will say N.
 
-SuperH 3/4 Watchdog
+SuperH Watchdog
 CONFIG_SH_WDT
   This driver adds watchdog support for the integrated watchdog in the
-  SuperH 3 and 4 processors. If you have one of these processors, say Y,
-  otherwise say N.
+  SuperH 3, 4 and 5 processors. If you have one of these processors, say
+  Y, otherwise say N.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -18051,6 +18811,12 @@
   Toshiba Linux utilities web site at:
   <http://www.buzzard.org.uk/toshiba/>.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  toshiba.o
+
   Say Y if you intend to run this kernel on a Toshiba portable.
   Say N otherwise.
 
@@ -18067,6 +18833,12 @@
   You can force loading on unsupported models by passing the
   parameter `force=1' to the module. Use at your own risk.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  i8k.o
+
   For more information on this driver and for utilities that make
   use of the module see the I8K Linux Utilities web site at:
   <http://www.debian.org/~dz/i8k/>.
@@ -18102,6 +18874,12 @@
   MSR accesses are directed to a specific CPU on multi-processor
   systems.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  msr.o
+
 /dev/cpu/*/cpuid - CPU information support
 CONFIG_X86_CPUID
   This device gives processes access to the x86 CPUID instruction to
@@ -18109,6 +18887,12 @@
   with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
   /dev/cpu/31/cpuid.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  cpuid.o
+
 SBC-60XX Watchdog Timer
 CONFIG_60XX_WDT
  This driver can be used with the watchdog timer found on some
@@ -18187,9 +18971,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
@@ -19406,6 +20191,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
@@ -19581,16 +20372,6 @@
   hardware debugging with a logic analyzer and need to see all traffic
   on the bus.
 
-AU1000 serial console
-CONFIG_AU1000_SERIAL_CONSOLE
-  If you have an Alchemy AU1000 processor (MIPS based) and you want
-  to use a console on a serial port, say Y.  Otherwise, say N.
-
-AU1000 serial support
-CONFIG_AU1000_UART
-  If you have an Alchemy AU1000 processor (MIPS based) and you want
-  to use serial ports, say Y.  Otherwise, say N.
-
 AU1000 ethernet controller on SGI MIPS system
 CONFIG_MIPS_AU1000_ENET
   If you have an Alchemy Semi AU1000 ethernet controller
@@ -19671,6 +20452,11 @@
   method as well for this to be useful. Even if they don't support it,
   it is safe to say Y here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called isdn_bsdcomp.o.
+
 Support audio via ISDN
 CONFIG_ISDN_AUDIO
   If you say Y here, the modem-emulator will support a subset of the
@@ -19705,6 +20491,11 @@
 
   Please read the file <file:Documentation/isdn/README.diversion>.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called dss1_divert.o.
+
 ICN 2B and 4B support
 CONFIG_ISDN_DRV_ICN
   This enables support for two kinds of ISDN-cards made by a German
@@ -19729,6 +20520,11 @@
   You need will need the loopctrl utility from the latest isdn4k-utils
   package to set up this driver.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called isdnloop.o.
+
 HiSax SiemensChipSet driver support
 CONFIG_ISDN_DRV_HISAX
   This is a driver supporting the Siemens chipset on various
@@ -19794,7 +20590,6 @@
   Enable this if you like to use ISDN in US on a NI1 basic rate
   interface.
 
-# 2.4 tree only
 Maximum number of cards supported by HiSax
 CONFIG_HISAX_MAX_CARDS
   This is used to allocate a driver-internal structure array with one
@@ -20024,15 +20819,30 @@
   This enables the PCMCIA client driver for the Elsa PCMCIA MicroLink
   card.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called elsa_cs.o.
+
 Sedlbauer PCMCIA cards
 CONFIG_HISAX_SEDLBAUER_CS
   This enables the PCMCIA client driver for the Sedlbauer Speed Star
   and Speed Star II cards.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called sedlbauer_cs.o.
+
 CONFIG_HISAX_AVM_A1_CS
   This enables the PCMCIA client driver for the AVM A1 / Fritz!Card
   PCMCIA cards.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called avma1_cs.o.
+
 ST5481 USB ISDN modem
 CONFIG_HISAX_ST5481
   This enables the driver for ST5481 based USB ISDN adapters,
@@ -20074,6 +20884,11 @@
   Say Y here to use your Eicon active ISDN card with ISDN4Linux
   isdn module.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called eicon.o.
+
 Eicon PCI DIVA Server BRI/PRI/4BRI support
 CONFIG_ISDN_DRV_EICON_PCI
   Say Y here if you have an Eicon Diva Server (BRI/PRI/4BRI) ISDN
@@ -20096,6 +20911,11 @@
   cards and will provide its own IDI interface. You should say N
   here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called divas.o.
+
 Support AT-Fax Class 1 and 2 commands
 CONFIG_ISDN_TTY_FAX
   If you say Y here, the modem-emulator will support a subset of the
@@ -20124,6 +20944,11 @@
   standardized libcapi20 to access this functionality.  You should say
   Y/M here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called capi.o.
+
 CAPI2.0 Middleware support
 CONFIG_ISDN_CAPI_MIDDLEWARE
   This option will enhance the capabilities of the /dev/capi20
@@ -20146,12 +20971,22 @@
   supported by a CAPI driver, but still want to use old features like
   ippp interfaces or ttyI emulation, say Y/M here.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called capidrv.o.
+
 AVM B1 ISA support
 CONFIG_ISDN_DRV_AVMB1_B1ISA
   Enable support for the ISA version of the AVM B1 card.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called b1isa.o.
+
 AVM B1 PCI support
-CONFIG_ISDN_DRV_AVMB1_B1PCI
+CONFIG_ISDN_DRV_AVMB1_B1CICI
   Enable support for the PCI version of the AVM B1 card.
 
 AVM B1 PCI V4 support
@@ -20163,25 +20998,50 @@
   Enable support for the AVM T1 T1B card.
   Note: This is a PRI card and handle 30 B-channels.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called t1isa.o.
+
 AVM B1/M1/M2 PCMCIA support
 CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
   Enable support for the PCMCIA version of the AVM B1 card.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called b1pcmcia.o.
+
 AVM B1/M1/M2 PCMCIA cs module
 CONFIG_ISDN_DRV_AVMB1_AVM_CS
   Enable the PCMCIA client driver for the AVM B1/M1/M2
   PCMCIA cards.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called avm_cs.o.
+
 AVM T1/T1-B PCI support
 CONFIG_ISDN_DRV_AVMB1_T1PCI
   Enable support for the AVM T1 T1B card.
   Note: This is a PRI card and handle 30 B-channels.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called t1pci.o.
+
 AVM C4/C2 support
 CONFIG_ISDN_DRV_AVMB1_C4
   Enable support for the AVM C4/C2 PCI cards.
   These cards handle 4/2 BRI ISDN lines (8/4 channels).
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called c4.o.
+
 Verbose reason code reporting (kernel size +=7K)
 CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
   If you say Y here, the AVM B1 driver will give verbose reasons for
@@ -20196,6 +21056,11 @@
   isdn4k-utils package. Please read the file
   <file:Documentation/isdn/README.act2000> for more information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called act2000.o.
+
 Auvertech TurboPAM support
 CONFIG_ISDN_DRV_TPAM
   This enables support for the Auvertech TurboPAM ISDN-card.
@@ -20217,6 +21082,11 @@
   Please read the file <file:Documentation/isdn/README.hysdn> for more
   information.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called hysdn.o.
+
 HYSDN CAPI 2.0 support
 CONFIG_HYSDN_CAPI
   Say Y here if you like to use Hypercope's CAPI 2.0 interface.
@@ -20283,7 +21153,7 @@
 
 Kernel support for 32-bit ELF binaries
 CONFIG_BINFMT_ELF32
-  This allows you to run 32-bit Linux/ELF binaries on your Ultra.
+  This allows you to run 32-bit Linux/ELF binaries on your machine.
   Everybody wants this; say Y.
 
 Kernel support for 32-bit (ie. SunOS) a.out binaries
@@ -20369,7 +21239,7 @@
 DBRI Lowlevel Driver
 CONFIG_SPARCAUDIO_DBRI
   This driver supports the DBRI audio interface found on the SS10,
-  SS20, Sparcbook 3, and Voyager systems.
+  SS20, LX, Sparcbook 3, and Voyager systems.
 
 Dummy Lowlevel Driver
 CONFIG_SPARCAUDIO_DUMMY
@@ -20436,6 +21306,19 @@
   Say Y here to compile SCO support into the kernel or say M to
   compile it as module (sco.o).
 
+BNEP protocol support
+CONFIG_BLUEZ_BNEP
+  BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
+  emulation layer on top of Bluetooth. BNEP is required for Bluetooth
+  PAN (Personal Area Network).
+
+  To use BNEP, you will need user-space utilities provided in the 
+  BlueZ-PAN package.
+  For more information, see <http://bluez.sourceforge.net>.
+
+  Say Y here to compile BNEP support into the kernel or say M to
+  compile it as module (bnep.o).
+
 HCI UART driver
 CONFIG_BLUEZ_HCIUART
   Bluetooth HCI UART driver.
@@ -20464,18 +21347,9 @@
   Say Y here to compile support for Bluetooth USB devices into the
   kernel or say M to compile it as module (hci_usb.o).
 
-HCI USB firmware download support
-CONFIG_BLUEZ_USB_FW_LOAD
-  Firmware download support for Bluetooth USB devices.
-  This support is required for devices like Broadcom BCM2033.
-
-  HCI USB driver uses external firmware downloader program provided 
-  in BlueFW package.
-  For more information, see <http://bluez.sf.net/>.
-
 HCI USB zero packet support
 CONFIG_BLUEZ_USB_ZERO_PACKET
-  Support for USB zero packets. 
+  Support for USB zero packets.
   This option is provided only as a work around for buggy Bluetooth USB 
   devices. Do _not_ enable it unless you know for sure that your device 
   requires zero packets.
@@ -20494,11 +21368,37 @@
   Bluetooth HCI DTL1 (PC Card) driver.
   This driver provides support for Bluetooth PCMCIA devices with
   Nokia DTL1 interface:
-     Nokia Bluetooth PC Card, Socketcom Bluetooth CF module
+     Nokia Bluetooth Card
+     Socket Bluetooth CF Card
 
   Say Y here to compile support for HCI DTL1 devices into the
   kernel or say M to compile it as module (dtl1_cs.o).
 
+HCI BT3C (PC Card) device driver
+CONFIG_BLUEZ_HCIBT3C
+  Bluetooth HCI BT3C (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  3Com BT3C interface:
+     3Com Bluetooth Card (3CRWB6096)
+     HP Bluetooth Card
+
+  The HCI BT3C driver uses external firmware loader program provided in
+  the BlueFW package. For more information, see <http://bluez.sf.net>.
+
+  Say Y here to compile support for HCI BT3C devices into the
+  kernel or say M to compile it as module (bt3c_cs.o).
+
+HCI BlueCard (PC Card) device driver
+CONFIG_BLUEZ_HCIBLUECARD
+  Bluetooth HCI BlueCard (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  Anycom BlueCard interface:
+     Anycom Bluetooth PC Card
+     Anycom Bluetooth CF Card
+
+  Say Y here to compile support for HCI BlueCard devices into the
+  kernel or say M to compile it as module (bluecard_cs.o).
+
 # The following options are for Linux when running on the Hitachi
 # SuperH family of RISC microprocessors.
 
@@ -20527,6 +21427,11 @@
 
   "Area6" will work for most boards. For ADX, select "Area5".
 
+Disable data cache
+CONFIG_DCACHE_DISABLE
+  This option allows you to run the kernel with data cache disabled.
+  Say Y if you experience CPM lock-ups.
+
 #
 # m68k-specific kernel options
 # Documented by Chris Lawrence <mailto:quango@themall.net> et al.
@@ -20931,12 +21836,6 @@
   Hades. This increases the SCSI transfer rates at least ten times
   compared to PIO transfers.
 
-Sun3 NCR5380 OBIO SCSI
-CONFIG_SUN3_SCSI
-  This option will enable support for the OBIO (onboard io) NCR5380
-  SCSI controller found in the Sun 3/50 and 3/60.  Note that this
-  driver does not provide support for VME SCSI boards.
-
 Sun3x ESP SCSI
 CONFIG_SUN3X_ESP
   This option will enable support for the ESP SCSI controller found
@@ -20990,11 +21889,6 @@
   General Linux information on the Sun 3 series (now discontinued)
   is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
-Sun3x ESP SCSI driver
-CONFIG_SUN3X_ESP
-  The ESP was an on-board SCSI controller used on Sun 3/80
-  machines.  Say Y here to compile in support for it.
-
 PCMCIA NE2000 and compatibles support
 CONFIG_APNE
   If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
@@ -21005,19 +21899,6 @@
   want). The module is called apne.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Sun3/Sun3x on-board LANCE support
-CONFIG_SUN3LANCE
-  This driver enables support for the on-board LANCE ethernet adapter
-  found on the Sun 3/50, 3/60, and 3/80 workstations.  If you have 
-  one of these workstations, and would like Ethernet, say Y. 
-  Otherwise, say N.
-
-Sun3 on-board Intel 82586 support
-CONFIG_SUN3_82586
-  This driver enables support for the on-board Intel 82586 based Ethernet
-  adapter found on Sun 3/1xx and 3/2xx motherboards.  Note that this driver
-  does not support 82586-based adapters on additional VME boards.
-
 Atari Lance support
 CONFIG_ATARILANCE
   Say Y to include support for several Atari Ethernet adapters based
@@ -21354,6 +22235,8 @@
   Select APUS if configuring for a PowerUP Amiga.  More information is
   available at: <http://linux-apus.sourceforge.net/>.
 
+  Note that Total Impact briQ is handled as a CHRP machine.
+
 Synergy-Gemini
 CONFIG_GEMINI
   Select Gemini if configuring for a Synergy Microsystems' Gemini
@@ -21712,7 +22595,7 @@
 
   CU824:
     VMEBus Board with PCI extension with MPC8240 CPU
-    Manufacturer: MicroSys GmbH, http://www.microsys.de/
+    Manufacturer: MicroSys GmbH, <http://www.microsys.de/>
     Date of Release: early 2001 (?)
     End of life: -
     URL: <http://www.microsys.de/html/cu824.html>
@@ -22398,7 +23281,7 @@
   IPL device on another question, that pops up, when you select
   CONFIG_IPL.
 
-IPL from a /390 tape unit
+IPL from a S/390 tape unit
 CONFIG_IPL_TAPE
   Select this option if you want to IPL the image from a Tape.
 
@@ -22407,18 +23290,22 @@
   Select this option if you are running under VM/ESA and want 
   to IPL the image from the emulated card reader.
 
-Support for DASD hard disks
-CONFIG_DASD
-  Enable this option if you want to access DASDs directly utilizing
-  S/390s channel subsystem commands. This is necessary for running
-  natively on a single image or an LPAR.
+CONFIG_PFAULT
+  Select this option, if you want to use PFAULT pseudo page fault
+  handling under VM. If running native or in LPAR, this option
+  has no effect. If your VM does not support PFAULT, PAGEEX
+  pseudo page fault handling will be used.
+  Note that VM 4.2 supports PFAULT but has a bug in its
+  implementation that causes some problems.
+  Everybody who wants to run Linux under VM != VM4.2 should select
+  this option.
 
-Enable DASD fast write
-CONFIG_DASD_FAST_IO
-  Enable fast I/O for DASDs. That means that the next I/O command
-  is already issued at interrupt time, if an I/O request is pending.
-  This option gives significant speedup of I/O, because we don't
-  schedule the bottom-halves as often as Intel.
+CONFIG_SHARED_KERNEL
+  Select this option, if you want to share the text segment of the
+  Linux kernel between different VM guests. This reduces memory
+  usage with lots of guests but greatly increases kernel size.
+  You should only select this option if you know what you are
+  doing and want to exploit this feature.
 
 Support for IBM-style disk-labels (S/390)
 CONFIG_S390_PARTITION
@@ -22427,18 +23314,40 @@
   attached to another IBM mainframe operation system (OS/390, 
   VM/ESA, VSE/ESA).
 
+Support for DASD hard disks
+CONFIG_DASD
+  Enable this option if you want to access DASDs directly utilizing
+  S/390s channel subsystem commands. This is necessary for running
+  natively on a single image or an LPAR.
+
 Support for ECKD hard disks
 CONFIG_DASD_ECKD
-  ECKD devices are the most commonly used devices. You should enable
-  this option unless you are very sure you have no ECKD device.
+  ECKD (Extended Count Key Data) devices are the most commonly used 
+  devices on S/390s. You should enable this option unless you are 
+  very sure you have no ECKD device.
 
-CKD devices
-CONFIG_DASD_CKD
-  CKD devices are currently unsupported.
+ECKD demand loading
+CONFIG_DASD_AUTO_ECKD
+  This option enables demand loading of the ECKD module. 
 
 Support for FBA hard disks
 CONFIG_DASD_FBA
-  FBA devices are currently unsupported.
+  Select this option if you want to use FBA (Fixed Block) devices.
+  If you are not sure what it is, say "Y".
+
+FBA demand loading
+CONFIG_DASD_AUTO_FBA
+  This option enables demand loading of the FBA module. 
+
+Support for DIAG access to CMS reserved Disks
+CONFIG_DASD_DIAG
+  Select this option if you want to use CMS reserved Disks under VM
+  with the Diagnose250 command.  If you are not running under VM or
+  unsure what it is, say "N".
+
+DIAG demand loading
+CONFIG_DASD_AUTO_DIAG
+  This option enables demand loading of the DIAG module. 
 
 Merge some code into the kernel to make the image IPLable
 CONFIG_IPLABLE
@@ -22476,6 +23385,16 @@
   Include support for using an IBM HWC line-mode terminal as the Linux
   system console.
 
+Control Program Identification
+CONFIG_HWC_CPI
+  Allows for Control Program Identification via the HWC interface,
+  i.e. provides a mean to pass an OS instance name (system name)
+  to the machine.
+
+  This option should only be selected as a module since the
+  system name has to be passed as module parameter. The module
+  will be called hwc_cpi.o.
+
 S/390 tape device support
 CONFIG_S390_TAPE
   Select this option if you want to access channel-attached tape
@@ -22484,8 +23403,9 @@
   least one of the tape interface options and one of the tape
   hardware options in order to access a tape device.
   This option is also available as a module. The module will be
-  called tape390.o and include all selected interfaces and
-  hardware drivers.
+  called tape390.o and include all selected interfaces.
+  The hardware drivers will be seperate modules.
+  If unsure, say "Y".
 
 Support for tape character devices
 CONFIG_S390_TAPE_CHAR
@@ -22506,14 +23426,23 @@
 
 Support for 3490 tape hardware
 CONFIG_S390_TAPE_3490
-  Select this option if you want to access IBM 3480 magnetic
+  Select this option if you want to access IBM 3490 magnetic
   tape subsystems and 100% compatibles.
+  This option is also available as a module. The module will be
+  called tape3490.o. If CONFIG_S390_TAPE is selected as a module,
+  this hardware driver cannot be built-in but is only available
+  as a module.
   It is safe to say "Y" here.
 
 Support for 3480 tape hardware
 CONFIG_S390_TAPE_3480
-  Select this option if you want to access IBM 3490 magnetic
+  Select this option if you want to access IBM 3480 magnetic
   tape subsystems and 100% compatibles.
+  This option is also available as a module. The module will be
+  called tape3480.o. If CONFIG_S390_TAPE is selected as a module,
+  this hardware driver cannot be built-in but is only available
+  as a module.
+  It is safe to say "Y" here.
 
 CTC device support
 CONFIG_CTC
@@ -22524,12 +23453,6 @@
   available.  This option is also available as a module which will be
   called ctc.o.  If you do not know what it is, it's safe to say "Y".
 
-Support for DIAG access to CMS reserved Disks
-CONFIG_DASD_DIAG
-  Select this option if you want to use CMS reserved Disks under VM
-  with the Diagnose250 command.  If you are not running under VM or
-  unsure what it is, say "N".
-
 XPRAM disk support
 CONFIG_BLK_DEV_XPRAM
   Select this option if you want to use your expanded storage on S/390
@@ -22552,6 +23475,20 @@
   vehicle networking under VM or VIF.  This option is also available
   as a module which will be called iucv.o. If unsure, say "Y".
 
+Process warning machine checks
+CONFIG_MACHCHK_WARNING
+  Select this option if you want the machine check handler on IBM S/390 or 
+  zSeries to process warning machine checks (e.g. on power failures). 
+  If unsure, say "Y".
+
+Use chscs for Common I/O
+CONFIG_CHSC
+  Select this option if you want the s390 common I/O layer to use information
+  obtained by channel subsystem calls. This will enable Linux to process link
+  failures and resource accessibility events. Moreover, if you have procfs
+  enabled, you'll be able to toggle chpids logically offline and online. Even
+  if you don't understand what this means, you should say "Y".
+
 Kernel support for 31 bit ELF binaries
 CONFIG_S390_SUPPORT
   Select this option if you want to enable your system kernel to
@@ -22608,6 +23545,12 @@
   supported by this driver, and for further information on the use of
   this driver.
 
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  cpqarray.o
+
 Show crashed user process info
 CONFIG_PROCESS_DEBUG
   Say Y to print all process fault locations to the console.  This is
@@ -23014,6 +23957,11 @@
   It is recommended to be used on a NetWinder, but it is not a
   necessity.
 
+Check for stack overflows
+CONFIG_DEBUG_STACKOVERFLOW
+  This option make do_IRQ() check for enough stack space beeing left.
+  This is safe to enable.
+
 Debug high memory support
 CONFIG_DEBUG_HIGHMEM
   This options enables addition error checking for high memory systems.
@@ -23222,13 +24170,24 @@
 
 SRM environment variables in procfs
 CONFIG_SRM_ENV
-  If you enable this option, a subdirectory called srm_environment
-  will give you access to the most important SRM environment
-  variables. If you've got an Alpha style system supporting
-  SRC, then it is a good idea to say Yes or Module to this driver.
+  If you enable this option, a subdirectory inside /proc called
+  /proc/srm_environment will give you access to the all important
+  SRM environment variables (those which have a name) and also
+  to all others (by their internal number).
+
+  SRM is something like a BIOS for Alpha machines. There are some
+  other such BIOSes, like AlphaBIOS, which this driver cannot
+  support (hey, that's not SRM!).
+
+  Despite the fact that this driver doesn't work on all Alphas (but
+  only on those which have SRM as their firmware), it's save to
+  build it even if your particular machine doesn't know about SRM
+  (or if you intend to compile a generic kernel). It will simply
+  not create those subdirectory in /proc (and give you some warning,
+  of course).
 
   This driver is also available as a module and will be called
-  srm_env.o if you build it as a module.
+  srm_env.o then.
 
 Footbridge internal watchdog
 CONFIG_21285_WATCHDOG
@@ -23449,6 +24408,11 @@
   This driver supports the use of zero copy on tx, checksum 
   validation on rx, and 64 bit addressing.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called ns83820.o.
+
 Toshiba Type-O IR Port device driver
 CONFIG_TOSHIBA_FIR
   Say Y here if you want to build support for the Toshiba Type-O IR
@@ -23505,6 +24469,11 @@
   used by IrTTY.  To activate support for ESI dongles you will have to
   start irattach like this: "irattach -d esi".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called esi.o.
+
 ACTiSYS IR-220L and IR220L+ dongle
 CONFIG_ACTISYS_DONGLE
   Say Y here if you want to build support for the ACTiSYS IR-220L and
@@ -23515,6 +24484,11 @@
   dongles you will have to start irattach like this:
   "irattach -d actisys" or "irattach -d actisys+".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called actisys.o.
+
 Tekram IrMate 210B dongle
 CONFIG_TEKRAM_DONGLE
   Say Y here if you want to build support for the Tekram IrMate 210B
@@ -23524,6 +24498,11 @@
   by IrTTY.  To activate support for Tekram dongles you will have to
   start irattach like this: "irattach -d tekram".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called tekram.o.
+
 Greenwich GIrBIL dongle
 CONFIG_GIRBIL_DONGLE
   Say Y here if you want to build support for the Greenwich GIrBIL
@@ -23533,6 +24512,11 @@
   used by IrTTY.  To activate support for Greenwich dongles you will
   have to insert "irattach -d girbil" in the /etc/irda/drivers script.
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called girbil.o.
+
 Parallax LiteLink dongle
 CONFIG_LITELINK_DONGLE
   Say Y here if you want to build support for the Parallax Litelink
@@ -23542,6 +24526,23 @@
   used by IrTTY.  To activate support for Parallax dongles you will
   have to start irattach like this "irattach -d litelink".
 
+  If you want to compile the driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called litelink.o.
+
+Microchip MCP2120 dongle
+CONFIG_MCP2120_DONGLE
+  Say Y here if you want to build support for the Microchip MCP2120
+  dongle.  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The MCP2120 dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY.  To activate support for MCP2120 dongles you will
+  have to insert "irattach -d mcp2120" in the /etc/irda/drivers script.
+
+  You must build this dongle yourself.  For more information see:
+  <http://www.eyetap.org/~tangf/irda_sir_linux.html>
+
 Old Belkin dongle
 CONFIG_OLD_BELKIN_DONGLE
   Say Y here if you want to build support for the Adaptec Airport 1000
@@ -23549,6 +24550,30 @@
   and read <file:Documentation/modules.txt>.  The module will be
   called old_belkin.o.  Some information is contained in the comments
   at the top of <file:drivers/net/irda/old_belkin.c>.
+ 
+ACTiSYS IR-200L dongle (Experimental)
+CONFIG_ACT200L_DONGLE
+  Say Y here if you want to build support for the ACTiSYS IR-200L
+  dongle. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The ACTiSYS IR-200L dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY. To activate support for ACTiSYS IR-200L dongles
+  you will have to start irattach like this: "irattach -d act200l".
+
+Mobile Action MA600 dongle (Experimental)
+CONFIG_MA600_DONGLE
+  Say Y here if you want to build support for the Mobile Action MA600
+  dongle.  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The MA600 dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  tested on IrCOMM.  To activate support for MA600 dongles you will
+  have to insert "irattach -d ma600" in the /etc/irda/drivers script.
+  Note: irutils 0.9.15 requires no modification. irutils 0.9.9 needs
+  modification. For more information, download the following tar gzip
+  file.
+
+  There is a pre-compiled module on
+  <http://engsvr.ust.hk/~eetwl95/download/ma600-2.4.x.tar.gz>
 
 VME (Motorola and BVM) support
 CONFIG_VME
@@ -24400,15 +25425,19 @@
   As of the time of this writing, most hardware is DIG compliant,
   so the "DIG-compliant" option is usually the right choice.
 
-  HP-simulator   For the HP simulator
-                 (<http://software.hp.com/ia64linux/>).
+  HP-simulator   For the HP simulator (<http://software.hp.com/ia64linux/>).
+  HP-zx1	 For HP zx1 Platforms.
   SN1            For SGI SN1 Platforms.
   SN2            For SGI SN2 Platforms.
-  DIG-compliant  For DIG ("Developer's Interface Guide") compliant
-                 system.
+  DIG-compliant  For DIG ("Developer's Interface Guide") compliant systems.
 
   If you don't know what to do, choose "generic".
 
+CONFIG_IA64_HP_ZX1
+  Build a kernel that runs on HP zx1-based systems.  This adds support
+  for the zx1 IOMMU and makes root bus bridges appear in PCI config space
+  (required for zx1 agpgart support).
+
 CONFIG_IA64_SGI_SN_SIM
   Build a kernel that runs on both the SGI simulator AND on hardware.
   There is a very slight performance penalty on hardware for including this
@@ -24456,16 +25485,6 @@
   can select this option to disable the VHPT for debugging.  If you're
   unsure, answer N.
 
-Enable McKinley A-step specific code
-CONFIG_MCKINLEY_ASTEP_SPECIFIC
-  Select this option to build a kernel for an IA64 McKinley system
-  with any A-stepping CPU.
-
-Enable McKinley A0/A1-step specific code
-CONFIG_MCKINLEY_A0_SPECIFIC
-  Select this option to build a kernel for an IA64 McKinley system
-  with an A0 or A1 stepping CPU.
-
 Turn on compare-and-exchange bug checking (slow!)
 CONFIG_IA64_DEBUG_CMPXCHG
   Selecting this option turns on bug checking for the IA64
@@ -24490,9 +25509,7 @@
 CONFIG_IA64_PRINT_HAZARDS
   Selecting this option prints more information for Illegal Dependency
   Faults, that is, for Read after Write, Write after Write or Write
-  after Read violations.  This option is ignored if you are compiling
-  for an Itanium A step processor (CONFIG_ITANIUM_ASTEP_SPECIFIC).  If
-  you're unsure, select Y.
+  after Read violations.  If you're unsure, select Y.
 
 Performance monitor support
 CONFIG_PERFMON
@@ -24526,15 +25543,6 @@
   the IA32 instruction set.  Say Y here to build in kernel support for
   this.  If in doubt, say Y.
 
-/proc/efi/vars support
-CONFIG_EFI_VARS
-  If you say Y here, you are able to get EFI (Extensible Firmware
-  Interface) variable information in /proc/efi/vars.  You may read,
-  write, create, and destroy EFI variables through this interface.
-
-  To use this option, you have to check that the "/proc file system
-  support" (CONFIG_PROC_FS) is enabled, too.
-
 Physical memory granularity (16 MB)
 CONFIG_IA64_GRANULE_16MB
   IA64 identity-mapped regions use a large page size.  We'll call such
@@ -24642,6 +25650,18 @@
   Include in-kernel hooks for the xmon kernel monitor/debugger
   supported by the PPC port.
 
+Include BDI2000 debugger support
+CONFIG_BDI_SWITCH
+  Include in-kernel support for the Abatron BDI2000 debugger.  To
+  learn more about the Abatron BDI2000, visit the web page at
+  <http://www.abatron.ch/>.
+
+Add additional CFLAGS to the kernel build
+CONFIG_MORE_COMPILE_OPTIONS
+  If you want to add additional CFLAGS to the kernel build, such as
+  -g for KGDB, XMON or the BDI2000, enable this option and then
+  enter what you would like to add in the next question.
+
 Include kgdb kernel debugger
 CONFIG_KWDB
   Include in-kernel hooks for kdb, the source level debugger for the
@@ -24998,7 +26018,7 @@
   ethernet interface does, including firewalling, bridging, and of course
   IP traffic.  You will need the 'vconfig' tool from the VLAN project in
   order to effectively use VLANs.  See the VLAN web page for more
-  information:  http://www.candelatech.com/~greear/vlan.html  If unsure,
+  information:  <http://www.candelatech.com/~greear/vlan.html>  If unsure,
   you can safely say 'N'.
 
 ARC console support
@@ -25020,14 +26040,6 @@
   <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
   board at <http://www.mvista.com/allies/semiconductor/ite.html>.
 
-Use chscs for Common I/O
-CONFIG_CHSC
-  Select this option if you want the s390 common I/O layer to use information
-  obtained by channel subsystem calls. This will enable Linux to process link
-  failures and resource accessibility events. Moreover, if you have procfs
-  enabled, you'll be able to toggle chpids logically offline and online. Even
-  if you don't understand what this means, you should say "Y".
-
 Support ARM926T processor
 CONFIG_CPU_ARM926T
   This is a variant of the ARM920.  It has slightly different
@@ -25047,21 +26059,6 @@
   written) to implement the policy. If you don't understand what this
   is all about, it's safe to say 'N'.
 
-Automatic activation of DIAG module
-CONFIG_DASD_AUTO_DIAG
-  Enable this option if you want your DIAG discipline module loaded
-  on DASD driver startup.
-
-Automatic activation of ECKD module
-CONFIG_DASD_AUTO_ECKD
-  Enable this option if you want your ECKD discipline module loaded
-  on DASD driver startup.
-
-Automatic activation of FBA  module
-CONFIG_DASD_AUTO_FBA
-  Enable this option if you want your FBA discipline module loaded
-  on DASD driver startup.
-
 SiS
 CONFIG_DRM_SIS
   Choose this option if you have a SIS graphics card. AGP support is
@@ -25155,16 +26152,6 @@
 
   When in doubt, say N.
 
-Control-Program Identification
-CONFIG_HWC_CPI
-  This option enables the hardware console interface for system
-  identification This is commonly used for workload management and
-  gives you a nice name for the system on the service element.
-  Please select this option as a module since built-in operation is
-  completely untested.
-  You should only select this option if you know what you are doing,
-  need this feature and intend to run your kernel in LPAR.
-
 Enable autotest (llsc). Option to run cache test instead of booting
 CONFIG_IA64_SGI_AUTOTEST
   Build a kernel used for hardware validation. If you include the
@@ -25240,37 +26227,12 @@
   Say Y here to support tuning the ITE8172's IDE interface.  This makes
   it possible to set DMA channel or PIO opration and the transfer rate.
 
-Process warning machine checks
-CONFIG_MACHCHK_WARNING
-  Select this option if you want the machine check handler on IBM S/390 or
-  zSeries to process warning machine checks (e.g. on power failures).
-  If unsure, say "Y".
-
-Pseudo page fault support
-CONFIG_PFAULT
-  Select this option, if you want to use PFAULT pseudo page fault
-  handling under VM. If running native or in LPAR, this option
-  has no effect. If your VM does not support PFAULT, PAGEEX
-  pseudo page fault handling will be used.
-  Note that VM 4.2 supports PFAULT but has a bug in its
-  implementation that causes some problems.
-  Everybody who wants to run Linux under VM != VM4.2 should select
-  this option.
-
 Enable protocol mode for the L1 console
 CONFIG_SERIAL_SGI_L1_PROTOCOL
   Uses protocol mode instead of raw mode for the level 1 console on the
   SGI SN (Scalable NUMA) platform for IA64.  If you are compiling for
   an SGI SN box then Y is the recommended value, otherwise say N.
 
-VM shared kernel support
-CONFIG_SHARED_KERNEL
-  Select this option, if you want to share the text segment of the
-  Linux kernel between different VM guests. This reduces memory
-  usage with lots of guests but greatly increases kernel size.
-  You should only select this option if you know what you are
-  doing and want to exploit this feature.
-
 New bus configuration (EXPERIMENTAL)  
 CONFIG_TULIP_MWI
   This configures your Tulip card specifically for the card and
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/Makefile linux-bk/Documentation/DocBook/Makefile
--- linux-2.4.19/Documentation/DocBook/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/DocBook/Makefile	2002-11-22 15:35:30.000000000 +0000
@@ -1,7 +1,8 @@
 BOOKS	:= wanbook.sgml z8530book.sgml mcabook.sgml videobook.sgml \
 	   kernel-api.sgml parportbook.sgml kernel-hacking.sgml \
 	   kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml \
-	   deviceiobook.sgml procfs-guide.sgml tulip-user.sgml
+	   deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \
+	   journal-api.sgml
 
 PS	:=	$(patsubst %.sgml, %.ps, $(BOOKS))
 PDF	:=	$(patsubst %.sgml, %.pdf, $(BOOKS))
@@ -138,6 +139,17 @@
 parportbook.sgml: parportbook.tmpl $(TOPDIR)/drivers/parport/init.c
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/parport/init.c <$< >$@
 
+
+JBDSOURCES :=  $(TOPDIR)/include/linux/jbd.h \
+	       $(TOPDIR)/fs/jbd/journal.c \
+	       $(TOPDIR)/fs/jbd/recovery.c \
+	       $(TOPDIR)/fs/jbd/transaction.c
+
+journal-api.sgml: journal-api.tmpl $(JBDSOURCES)
+	$(TOPDIR)/scripts/docgen   $(JBDSOURCES) \
+		<journal-api.tmpl >journal-api.sgml
+
+
 DVI	:=	$(patsubst %.sgml, %.dvi, $(BOOKS))
 AUX	:=	$(patsubst %.sgml, %.aux, $(BOOKS))
 TEX	:=	$(patsubst %.sgml, %.tex, $(BOOKS))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/journal-api.tmpl linux-bk/Documentation/DocBook/journal-api.tmpl
--- linux-2.4.19/Documentation/DocBook/journal-api.tmpl	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/DocBook/journal-api.tmpl	2002-11-22 15:35:24.000000000 +0000
@@ -0,0 +1,297 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+<book id="LinuxJBDAPI">
+ <bookinfo>
+  <title>The Linux Journalling API</title>
+  <authorgroup>
+  <author>
+     <firstname>Roger</firstname>
+     <surname>Gammans</surname>
+     <affiliation>
+     <address>
+      <email>rgammans@computer-surgery.co.uk</email>
+     </address>
+    </affiliation>
+     </author> 
+  </authorgroup>
+  
+  <authorgroup>
+   <author>
+    <firstname>Stephen</firstname>
+    <surname>Tweedie</surname>
+    <affiliation>
+     <address>
+      <email>sct@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2002</year>
+   <holder>Roger Gammans</holder>
+  </copyright>
+
+<legalnotice>
+   <para>
+     This documentation is free software; you can redistribute
+     it and/or modify it under the terms of the GNU General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later
+     version.
+   </para>
+      
+   <para>
+     This program is distributed in the hope that it will be
+     useful, but WITHOUT ANY WARRANTY; without even the implied
+     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+     See the GNU General Public License for more details.
+   </para>
+      
+   <para>
+     You should have received a copy of the GNU General Public
+     License along with this program; if not, write to the Free
+     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+     MA 02111-1307 USA
+   </para>
+      
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="Overview">
+     <title>Overview</title>
+  <sect1>
+     <title>Details</title>
+<para>
+The journalling layer is  easy to use. You need to 
+first of all create a journal_t data structure. There are
+two calls to do this dependent on how you decide to allocate the physical
+media on which the journal resides. The journal_init_inode() call 
+is for journals stored in filesystem inodes, or the journal_init_dev()
+call can be use for journal stored on a raw device (in a continuous range 
+of blocks). A journal_t is a typedef for a struct pointer, so when
+you are finally finished make sure you call journal_destroy() on it
+to free up any used kernel memory.
+</para>
+
+<para>
+Once you have got your journal_t object you need to 'mount' or load the journal
+file, unless of course you haven't initialised it yet - in which case you
+need to call journal_create().
+</para>
+
+<para>
+Most of the time however your journal file will already have been created, but
+before you load it you must call journal_wipe() to empty the journal file.
+Hang on, you say , what if the filesystem wasn't cleanly umount()'d . Well, it is the 
+job of the client file system to detect this and skip the call to journal_wipe().
+</para>
+
+<para>
+In either case the next call should be to journal_load() which prepares the
+journal file for use. Note that journal_wipe(..,0) calls journal_skip_recovery() 
+for you if it detects any outstanding transactions in the journal and similarly
+journal_load() will call journal_recover() if necessary.
+I would advise reading fs/ext3/super.c for examples on this stage.
+[RGG: Why is the journal_wipe() call necessary - doesn't this needlessly 
+complicate the API. Or isn't a good idea for the journal layer to hide 
+dirty mounts from the client fs]
+</para>
+
+<para>
+Now you can go ahead and start modifying the underlying 
+filesystem. Almost.
+</para>
+
+
+<para>
+
+You still need to actually journal your filesystem changes, this
+is done by wrapping them into transactions. Additionally you
+also need to wrap the modification of each of the the buffers
+with calls to the journal layer, so it knows what the modifications
+you are actually making are. To do this use  journal_start() which
+returns a transaction handle.
+</para>
+
+<para>
+journal_start()
+and its counterpart journal_stop(), which indicates the end of a transaction
+are nestable calls, so you can reenter a transaction if necessary,
+but remember you must call journal_stop() the same number of times as
+journal_start() before the transaction is completed (or more accurately
+leaves the the update phase). Ext3/VFS makes use of this feature to simplify 
+quota support.
+</para>
+
+<para>
+Inside each transaction you need to wrap the modifications to the
+individual buffers (blocks). Before you start to modify a buffer you
+need to call journal_get_{create,write,undo}_access() as appropriate,
+this allows the journalling layer to copy the unmodified data if it
+needs to. After all the buffer may be part of a previously uncommitted
+transaction. 
+At this point you are at last ready to modify a buffer, and once
+you are have done so you need to call journal_dirty_{meta,}data().
+Or if you've asked for access to a buffer you now know is now longer 
+required to be pushed back on the device you can call journal_forget()
+in much the same way as you might have used bforget() in the past.
+
+</para>
+
+
+
+<para>
+A journal_flush() may be called at any time to commit and checkpoint
+all your transactions.
+</para>
+<para>
+
+Then at umount time , in your put_super() (2.4) or write_super() (2.5)
+you can then call journal_destroy() to clean up your in-core journal object.
+</para>
+
+
+<para>
+Unfortunately there a couple of ways the journal layer can cause a deadlock.
+The first thing to note is that each task can only have
+a single outstanding transaction at any one time, remember nothing
+commits until the outermost journal_stop(). This means
+you must complete the transaction at the end of each file/inode/address
+etc. operation you perform, so that the journalling system isn't re-entered
+on another journal. Since transactions can't be nested/batched 
+across differing journals, and another filesystem other than
+yours (say ext3) may be modified in a later syscall.
+</para>
+<para>
+
+The second case to bear in mind is that journal_start() can 
+block if there isn't enough space in the journal for your transaction 
+(based on the passed nblocks param) - when it blocks it merely(!) needs to
+wait for transactions to complete and be committed from other tasks, 
+so essentially we are waiting for journal_stop(). So to avoid 
+deadlocks you must treat journal_start/stop() as if they
+were semaphores and include them in your semaphore ordering rules to prevent 
+deadlocks. Note that journal_extend() has similar blocking behaviour to
+journal_start() so you can deadlock here just as easily as on journal_start().
+</para>
+<para>
+
+Try to reserve the right number of blocks the first time. ;-).
+</para>
+<para>
+Another wriggle to watch out for is your on-disk block allocation strategy.
+why? Because, if you undo a delete, you need to ensure you haven't reused any
+of the freed blocks in a later transaction. One simple way of doing this
+is make sure any blocks you allocate only have checkpointed transactions
+listed against them. Ext3 does this in ext3_test_allocatable(). 
+</para>
+
+<para>
+Lock is also providing through journal_{un,}lock_updates(),
+ext3 uses this when it wants a window with a clean and stable fs for a moment.
+eg. 
+<programlisting>
+
+	journal_lock_updates() //stop new stuff happening..
+	journal_flush()        // checkpoint everything.
+	..do stuff on stable fs
+	journal_unlock_updates() // carry on with filesystem use.
+</programlisting>
+
+The opportunities for abuse and DOS attacks with this should be obvious,
+if you allow unprivileged userspace to trigger codepaths containing these
+calls.
+
+<para>
+</sect1>
+<sect1>
+<title>Summary</title>
+<para>
+Using the journal is a matter of wrapping the different context changes,
+being each mount, each modification (transaction) and each changed buffer
+to tell the journalling layer about them.
+
+Here is a some pseudo code to give you an idea of how it works, as
+an example.
+<programlisting>
+  journal_t* my_jnrl = journal_create();
+  journal_init_{dev,inode}(jnrl,...)
+  if (clean) journal_wipe();
+  journal_load();
+
+   foreach(transaction) { /*transactions must be 
+                            completed before
+                            a syscall returns to 
+                            userspace*/
+
+          handle_t * xct=journal_start(my_jnrl);
+          foreach(bh) {
+                journal_get_{create,write,undo}_access(xact,bh);
+                if ( myfs_modify(bh) ) { /* returns true 
+                                        if makes changes */
+                           journal_dirty_{meta,}data(xact,bh);
+                } else {
+                           journal_forget(bh);
+                }
+          }
+          journal_stop(xct);
+   }
+   journal_destroy(my_jrnl);
+</programlisting>
+
+</chapter>
+
+  <chapter id="adt">
+     <title>Data Types</title>
+     <para>	
+	The journalling layer uses typedefs to 'hide' the concrete definitions
+	of the structures used. As a client of the JBD layer you can
+	just rely on the using the pointer as a magic cookie  of some sort.
+	
+	Obviously the hiding is not enforced as this is 'C'.
+	</para>
+	<sect1><title>Structures</title>
+!Iinclude/linux/jbd.h
+	</sect1>
+</chapter>
+
+  <chapter id="calls">
+     <title>Functions</title>
+     <para>	
+	The functions here are split into two groups those that
+	affect a journal as a whole, and those which are used to
+	manage transactions
+</para>
+	<sect1><title>Journal Level</title>
+!Efs/jbd/journal.c
+!Efs/jbd/recovery.c
+	</sect1>
+	<sect1><title>Transasction Level</title>
+!Efs/jbd/transaction.c	
+	</sect1>
+</chapter>
+<chapter>
+     <title>See also</title>
+	<para>
+	<citation>
+	   <ulink url="ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/journal-design.ps.gz">
+	   	Journaling the Linux ext2fs Filesystem,LinuxExpo 98, Stephen Tweedie
+	   </ulink>
+	   </citation>
+	   </para>
+	   <para>
+	   <citation>
+	   <ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html">
+	   	Ext3 Journalling FileSystem , OLS 2000, Dr. Stephen Tweedie
+	   </ulink>
+	   </citation>
+	   </para>
+</chapter>
+
+</book>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/kernel-hacking.tmpl linux-bk/Documentation/DocBook/kernel-hacking.tmpl
--- linux-2.4.19/Documentation/DocBook/kernel-hacking.tmpl	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/DocBook/kernel-hacking.tmpl	2002-11-22 15:35:31.000000000 +0000
@@ -1091,18 +1091,17 @@
    <title>Initializing structure members</title>
 
    <para>
-    The preferred method of initializing structures is to use the
-    gcc Labeled Elements extension, eg:
+    The preferred method of initializing structures is to use
+    designated initialisers, as defined by ISO C99, eg:
    </para>
    <programlisting>
 static struct block_device_operations opt_fops = {
-        open:                   opt_open,
-        release:                opt_release,
-        ioctl:                  opt_ioctl,
-        check_media_change:     opt_media_change,
+        .open               = opt_open,
+        .release            = opt_release,
+        .ioctl              = opt_ioctl,
+        .check_media_change = opt_media_change,
 };
    </programlisting>
-
    <para>
     This makes it easy to grep for, and makes it clear which
     structure fields are set.  You should do this because it looks
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/DocBook/parportbook.tmpl linux-bk/Documentation/DocBook/parportbook.tmpl
--- linux-2.4.19/Documentation/DocBook/parportbook.tmpl	2001-10-25 07:07:40.000000000 +0000
+++ linux-bk/Documentation/DocBook/parportbook.tmpl	2002-11-22 15:35:23.000000000 +0000
@@ -595,7 +595,7 @@
    So, the first thing for the device driver to do is tell
    <literal>parport</literal> that it wants to know what parallel
    ports are on the system.  To do this, it uses the
-   <function>parport_register_device</function> function:
+   <function>parport_register_driver</function> function:
   </para>
 
   <funcsynopsis>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/SubmittingDrivers linux-bk/Documentation/SubmittingDrivers
--- linux-2.4.19/Documentation/SubmittingDrivers	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/SubmittingDrivers	2002-11-22 15:35:32.000000000 +0000
@@ -2,9 +2,8 @@
 ---------------------------------------
 
 This document is intended to explain how to submit device drivers to the
-Linux 2.2 and 2.4 kernel trees. Note that if you are interested in video
-card drivers you should probably talk to XFree86 (http://www.xfree86.org) 
-instead.
+various kernel trees. Note that if you are interested in video card drivers
+you should probably talk to XFree86 (http://www.xfree86.org) instead.
 
 Also read the Documentation/SubmittingPatches document.
 
@@ -35,21 +34,22 @@
 	maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk>
 
 Linux 2.4:
-	This kernel tree is under active development. The same rules apply
-	as 2.2 but you may wish to submit your driver via linux-kernel (see
-	resources) and follow that list to track changes in API's. These
-	should no longer be occuring as we are now in a code freeze.
-	The final contact point for Linux 2.4 submissions is 	
-	<torvalds@transmeta.com>.
+	The same rules apply as 2.2. The final contact point for Linux 2.4 
+	submissions is Marcelo Tosatti <marcelo@conectiva.com.br>.
+
+Linux 2.5:
+	The same rules apply as 2.4 except that you should follow linux-kernel
+	to track changes in API's. The final contact point for Linux 2.5
+	submissions is Linus Torvalds <torvalds@transmeta.com>.
 
 What Criteria Determine Acceptance
 ----------------------------------
 
-Licensing:	The code must be released to us under the GNU General Public License. 
-		We don't insist on any kind of exclusively GPL licensing,
-		and if you wish the driver to be useful to other communities
-		such as BSD you may well wish to release under multiple
-		licenses.
+Licensing:	The code must be released to us under the
+		GNU General Public License. We don't insist on any kind
+		of exclusively GPL licensing, and if you wish the driver
+		to be useful to other communities such as BSD you may well
+		wish to release under multiple licenses.
 
 Interfaces:	If your driver uses existing interfaces and behaves like
 		other drivers in the same class it will be much more likely
@@ -64,12 +64,13 @@
 		maintain them just once seperate them out nicely and note
 		this fact.
 
-Portability:	Pointers are not always 32bits, people do not all have
-		floating point and you shouldn't use inline x86 assembler in 
-		your driver without careful thought. Pure x86 drivers
-		generally are not popular. If you only have x86 hardware it 
-		is hard to test portability but it is easy to make sure the
-		code can easily be made portable.
+Portability:	Pointers are not always 32bits, not all computers are little
+		endian, people do not all have floating point and you
+		shouldn't use inline x86 assembler in your driver without
+		careful thought. Pure x86 drivers generally are not popular.
+		If you only have x86 hardware it is hard to test portability
+		but it is easy to make sure the code can easily be made
+		portable.
 
 Clarity:	It helps if anyone can see how to fix the driver. It helps
 		you because you get patches not bug reports. If you submit a
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/SubmittingPatches linux-bk/Documentation/SubmittingPatches
--- linux-2.4.19/Documentation/SubmittingPatches	2000-12-04 01:48:18.000000000 +0000
+++ linux-bk/Documentation/SubmittingPatches	2002-11-22 15:35:23.000000000 +0000
@@ -161,7 +161,7 @@
 When sending patches to Linus, always follow step #6.
 
 Large changes are not appropriate for mailing lists, and some
-maintainers.  If your patch, uncompressed, exceeds 40Kb in size,
+maintainers.  If your patch, uncompressed, exceeds 40 kB in size,
 it is preferred that you store your patch on an Internet-accessible
 server, and provide instead a URL (link) pointing to your patch.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/cdrom/sonycd535 linux-bk/Documentation/cdrom/sonycd535
--- linux-2.4.19/Documentation/cdrom/sonycd535	1998-05-21 01:54:34.000000000 +0000
+++ linux-bk/Documentation/cdrom/sonycd535	2002-11-22 15:35:28.000000000 +0000
@@ -63,8 +63,8 @@
 Thanks also to Eberhard Moenkeberg (emoenke@gwdg.de) for prodding
 me to place this code into the mainstream Linux source tree
 (as of Linux version 1.1.91), as well as some patches to make
-it a better device citizen.  Further thanks to "S. Joel Katz"
-<stimpson@panix.com> for his MODULE patches (see details below),
+it a better device citizen.  Further thanks to Joel Katz
+<joelkatz@webchat.org> for his MODULE patches (see details below),
 Porfiri Claudio <C.Porfiri@nisms.tei.ericsson.se> for patches
 to make the driver work with the older CDU-510/515 series, and
 Heiko Eissfeldt <heiko@colossus.escape.de> for pointing out that
@@ -79,7 +79,7 @@
 ken@halcyon.com
 
 ------------------------------------------------------------------------------
-(The following is from Joel Katz <Stimpson@Panix.COM>.)
+(The following is from Joel Katz <joelkatz@webchat.org>.)
 
 	To build a version of sony535.o that can be installed as a module,
 use the following command:
@@ -103,7 +103,7 @@
 	I have an external drive, and I usually leave it powered off. I used
 to have to reboot if I needed to use the CDROM drive. Now I don't.
 
-	Even if you have an internal drive, why waste the 268K of memory
+	Even if you have an internal drive, why waste the 96K of memory
 (unswappable) that the driver uses if you use your CD-ROM drive infrequently?
 
 	This driver will not install (whether compiled in or loaded as a
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/00-INDEX linux-bk/Documentation/filesystems/00-INDEX
--- linux-2.4.19/Documentation/filesystems/00-INDEX	2001-06-20 18:10:27.000000000 +0000
+++ linux-bk/Documentation/filesystems/00-INDEX	2002-11-22 15:35:30.000000000 +0000
@@ -6,6 +6,8 @@
 	- info and mount options for the Acorn Advanced Disc Filing System.
 affs.txt
 	- info and mount options for the Amiga Fast File System.
+befs.txt
+	- info for the BeOS file system (BFS)
 bfs.txt
 	- info for the SCO UnixWare Boot Filesystem (BFS).
 coda.txt
@@ -22,6 +24,8 @@
 	- info and mount options for the OS/2 HPFS.
 isofs.txt
 	- info and mount options for the ISO 9660 (CDROM) filesystem.
+jfs.txt
+	- info and mount options for the JFS filesystem.
 ncpfs.txt
 	- info on Novell Netware(tm) filesystem using NCP protocol.
 ntfs.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/Locking linux-bk/Documentation/filesystems/Locking
--- linux-2.4.19/Documentation/filesystems/Locking	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/filesystems/Locking	2002-11-22 15:35:27.000000000 +0000
@@ -45,6 +45,10 @@
 	int (*revalidate) (struct dentry *);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct dentry *, struct iattr *);
+	int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
+	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+	ssize_t (*listxattr) (struct dentry *, char *, size_t);
+	int (*removexattr) (struct dentry *, const char *);
 
 locking rules:
 	all may block
@@ -61,9 +65,13 @@
 follow_link:	no	no		no
 truncate:	yes	yes		no		(see below)
 setattr:	yes	if ATTR_SIZE	no
-permssion:	yes	no		no
+permission:	yes	no		no
 getattr:						(see below)
 revalidate:	no					(see below)
+setxattr:	yes	yes		no
+getxattr:	yes	yes		no
+listxattr:	yes	yes		no
+removexattr:	yes	yes		no
 	Additionally, ->rmdir() has i_zombie on victim and so does ->rename()
 in case when target exists and is a directory.
 	->rename() on directories has (per-superblock) ->s_vfs_rename_sem.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/befs.txt linux-bk/Documentation/filesystems/befs.txt
--- linux-2.4.19/Documentation/filesystems/befs.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/filesystems/befs.txt	2002-11-22 15:35:25.000000000 +0000
@@ -0,0 +1,111 @@
+BeOS filesystem for Linux
+
+Document last updated: Dec 6, 2001
+
+WARNING
+=======
+Make sure you understand that this is alpha software.  This means that the
+implementation is neither complete nor well-tested. 
+
+I DISCLAIM ALL RESPONSIBILTY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
+
+LICENSE
+=====
+This software is covered by the GNU General Public License. 
+See the file COPYING for the complete text of the license.
+Or the GNU website: <http://www.gnu.org/licenses/licenses.html>
+
+AUTHOR
+=====
+Current maintainer: Will Dyson <will_dyson@pobox.com>
+Has been working on the code since Aug 13, 2001. See the changelog for details.
+
+Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+His orriginal code can still be found at: <http://hp.vector.co.jp/authors/VA008030/bfs/>
+Does anyone know of a more current email address for Makoto? He doesn't respond
+to the address given above...
+
+WHAT IS THIS DRIVER?
+==================
+This module implements the native filesystem of BeOS <http://www.be.com/>
+for the linux 2.4.1 and later kernels. Currently it is a read-only implementation.
+
+Which is it, BFS or BEFS?
+================
+Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
+But Unixware Boot Filesystem is called bfs, too. And they are already in the
+kernel.
+Because of this nameing conflict, on Linux the BeOS filesystem is called befs.
+
+HOW TO INSTALL
+==============
+step 1.  Install the BeFS  patch into the source code tree of linux.
+
+Apply the patchfile to your kernel source tree.
+Assuming that your kernel source is in /foo/bar/linux and the patchfile is called
+patch-befs-xxx, you would do the following:
+
+	cd /foo/bar/linux
+	patch -p1 < /path/to/patch-befs-xxx
+
+if the patching step fails (i.e. there are rejected hunks), you can try to
+figure it out yourself (it shouldn't be hard), or mail the maintainer 
+(Will Dyson <will_dyson@pobox.com>) for help.
+
+step 2.  Configuretion & make kernel
+
+The linux kernel has many compile-time options. Most of them are beyond the
+scope of this document. I suggest the Kernel-HOWTO document as a good general
+reference on this topic. <http://www.linux.com/howto/Kernel-HOWTO.html>
+
+However, to use the BeFS module, you must enable it at configure time.
+
+	cd /foo/bar/linux
+	make menuconfig (or xconfig)
+
+The BeFS module is not a standard part of the linux kernel, so you must first
+enable support for experimental code under the "Code maturity level" menu.
+
+Then, under the "Filesystems" menu will be an option called "BeFS filesystem (experimental)",
+or something like that. Enable that option (it is fine to make it a module).
+
+Save your kernel configuration and then build your kernel.
+
+step 3.  Install
+
+See the kernel howto <http://www.linux.com/howto/Kernel-HOWTO.html> for
+instructions on this critical step.
+
+USING BFS
+=========
+To use the BeOS filesystem, use filesystem type 'befs'.
+
+ex)
+    mount -t befs /dev/fd0 /beos
+
+MOUNT OPTIONS
+=============
+uid=nnn        All files in the partition will be owned by user id nnn.
+gid=nnn	       All files in the partition will be in group nnn.
+iocharset=xxx  Use xxx as the name of the NLS translation table.
+debug          The driver will output debugging information to the syslog.
+
+HOW TO GET LASTEST VERSION
+==========================
+
+The latest version is currently available at:
+<http://befs-driver.sourceforge.net/>
+
+ANY KNOWN BUGS?
+===========
+As of Jan 20, 2002:
+	
+	None
+
+SPECIAL THANKS
+==============
+Dominic Giampalo ... Writing "Practical file system design with Be filesystem"
+Hiroyuki Yamada  ... Testing LinuxPPC.
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/devfs/ChangeLog linux-bk/Documentation/filesystems/devfs/ChangeLog
--- linux-2.4.19/Documentation/filesystems/devfs/ChangeLog	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/filesystems/devfs/ChangeLog	2002-11-22 15:35:25.000000000 +0000
@@ -1936,3 +1936,17 @@
 
 - Protected <scan_dir_for_removable> and <get_removable_partition>
   from changing directory contents
+===============================================================================
+Changes for patch v199.15
+
+- Switched to ISO C structure field initialisers
+
+- Switch to set_current_state() and move before add_wait_queue()
+
+- Updated README from master HTML file
+
+- Fixed devfs entry leak in <devfs_readdir> when *readdir fails
+===============================================================================
+Changes for patch v199.16
+
+- Fixed module unload race in <devfs_open>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/devfs/README linux-bk/Documentation/filesystems/devfs/README
--- linux-2.4.19/Documentation/filesystems/devfs/README	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/filesystems/devfs/README	2002-11-22 15:35:29.000000000 +0000
@@ -3,7 +3,7 @@
 
 Linux Devfs (Device File System) FAQ
 Richard Gooch
-7-APR-2002
+21-JUL-2002
 
 
 Document languages:
@@ -788,6 +788,9 @@
 make sure the kernel does not mount devfs at boot time
 
 
+make sure you have a correct /dev/console entry in your
+root file-system (where your disc-based /dev lives)
+
 create the /dev-state directory
 
 
@@ -1288,9 +1291,10 @@
 
 SCSI Generic Devices
 
-All SCSI CD-ROMs are placed under /dev/sg. A similar naming
-scheme is used as for SCSI discs. A SCSI generic device with the
-parameters:c=1,b=2,t=3,u=4 would appear as:
+The generic (aka. raw) interface for all SCSI devices are placed under
+/dev/sg. A similar naming scheme is used as for SCSI discs. A
+SCSI generic device with the parameters:c=1,b=2,t=3,u=4 would appear
+as:
 
 	/dev/sg/c1b2t3u4
 
@@ -1605,6 +1609,23 @@
 do that.
 
 
+I have extra or incorrect entries in /dev
+
+You may have stale entries in your dev-state area. Check for a
+RESTORE configuration line in your devfsd configuration
+(typically /etc/devfsd.conf). If you have this line, check
+the contents of the specified directory for stale entries. Remove
+any entries which are incorrect, then reboot.
+
+
+I get "Unable to open initial console" messages at boot
+
+This usually happens when you don't have devfs automounted onto
+/dev at boot time, and there is no valid
+/dev/console entry on your root file-system. Create a valid
+/dev/console device node.
+
+
 
 
 
@@ -1756,7 +1777,7 @@
 First, remember that no naming scheme will please everybody. You hate
 the scheme, others love it. Who's to say who's right and who's wrong?
 Ultimately, the person who writes the code gets to choose, and what
-exists now is a combination of the the choices made by the
+exists now is a combination of the choices made by the
 devfs author and the
 kernel maintainer (Linus).
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/isofs.txt linux-bk/Documentation/filesystems/isofs.txt
--- linux-2.4.19/Documentation/filesystems/isofs.txt	1999-05-26 17:01:43.000000000 +0000
+++ linux-bk/Documentation/filesystems/isofs.txt	2002-11-22 15:35:24.000000000 +0000
@@ -29,3 +29,10 @@
   unhide        Show hidden files.
   session=x     Select number of session on multisession CD
   sbsector=xxx  Session begins from sector xxx
+
+Recommended documents about ISO 9660 standard are located at:
+http://www.y-adagio.com/public/standards/iso_cdromr/tocont.htm
+ftp://ftp.ecma.ch/ecma-st/Ecma-119.pdf
+Quoting from the PDF "This 2nd Edition of Standard ECMA-119 is technically 
+identical with ISO 9660.", so it is a valid and gratis substitute of the
+official ISO specification.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/jfs.txt linux-bk/Documentation/filesystems/jfs.txt
--- linux-2.4.19/Documentation/filesystems/jfs.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/filesystems/jfs.txt	2002-11-22 15:35:31.000000000 +0000
@@ -0,0 +1,43 @@
+IBM's Journaled File System (JFS) for Linux
+
+JFS Homepage:  http://oss.software.ibm.com/jfs/
+
+Team members
+------------
+Steve Best         sbest@us.ibm.com
+Dave Kleikamp      shaggy@austin.ibm.com  
+Barry Arndt        barndt@us.ibm.com
+Christoph Hellwig  hch@infradead.org
+
+The following mount options are supported:
+
+iocharset=name	Character set to use for converting from Unicode to
+		ASCII.  The default is compiled into the kernel as
+		CONFIG_NLS_DEFAULT.  Use iocharset=utf8 for UTF8
+		translations.  This requires CONFIG_NLS_UTF8 to be set
+		in the kernel .config file.
+
+resize=value	Resize the volume to <value> blocks.  JFS only supports
+		growing a volume, not shrinking it.  This option is only
+		valid during a remount, when the volume is mounted
+		read-write.  The resize keyword with no value will grow
+		the volume to the full size of the partition.
+
+JFS TODO list:
+
+Plans for our near term development items
+
+   - enhance support for logfile on dedicated partition
+   - get access control list functionality operational
+   - get extended attributes functionality operational
+
+Longer term work items
+
+   - implement defrag utility, for online defragmenting
+   - add quota support
+   - add support for block sizes (512,1024,2048)
+
+Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+
+The JFS mailing list can be subscribed to by using the link labeled
+"Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/filesystems/proc.txt linux-bk/Documentation/filesystems/proc.txt
--- linux-2.4.19/Documentation/filesystems/proc.txt	2001-11-07 22:39:36.000000000 +0000
+++ linux-bk/Documentation/filesystems/proc.txt	2002-11-22 15:35:26.000000000 +0000
@@ -708,36 +708,26 @@
 used ones  is  far  behind,  you've  encountered  a peak in your usage of file
 handles and you don't need to increase the maximum.
 
-inode-state, inode-nr and inode-max
------------------------------------
-
-As with  file  handles, the kernel allocates the inode structures dynamically,
-but can't free them yet.
-
-The value  in  inode-max  denotes  the  maximum number of inode handlers. This
-value should  be  3 to 4 times larger than the value in file-max, since stdin,
-stdout, and  network  sockets also need an inode struct to handle them. If you
-regularly run out of inodes, you should increase this value.
+inode-state and inode-nr
+------------------------
 
 The file inode-nr contains the first two items from inode-state, so we'll skip
 to that file...
 
-inode-state contains  three  actual numbers and four dummy values. The numbers
-are nr_inodes, nr_free_inodes, and preshrink (in order of appearance).
+inode-state contains  two  actual numbers and five dummy values. The numbers
+are nr_inodes and nr_free_inodes (in order of appearance).
 
 nr_inodes
 ~~~~~~~~~
 
-Denotes the  number  of  inodes the system has allocated. This can be slightly
-more than inode-max because Linux allocates them one pageful at a time.
+Denotes the  number  of  inodes the system has allocated. This number will
+grow and shrink dynamically.
 
 nr_free_inodes
 --------------
 
-Represents the  number  of free inodes and preshrink is nonzero when nr_inodes
-is greater than inode-max and the system needs to prune the inode list instead
-of allocating more.
-
+Represents the  number of free inodes. Ie. The number of inuse inodes is
+(nr_inodes - nr_free_inodes).
 
 super-nr and super-max
 ----------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/ide.txt linux-bk/Documentation/ide.txt
--- linux-2.4.19/Documentation/ide.txt	2001-09-07 16:28:38.000000000 +0000
+++ linux-bk/Documentation/ide.txt	2002-11-22 15:35:24.000000000 +0000
@@ -306,6 +306,9 @@
  "idex=serialize"	: do not overlap operations on idex and ide(x^1)
  "idex=reset"		: reset interface after probe
  "idex=dma"		: automatically configure/use DMA if possible.
+ "idex=nohighio"	: don't use i/o to high memory addresses on this
+			 	interface. i/o to memory locations higher
+				than ~860MiB will be bounced.
 
  The following are valid ONLY on ide0,
  and the defaults for the base,ctl ports must not be altered.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/initrd.txt linux-bk/Documentation/initrd.txt
--- linux-2.4.19/Documentation/initrd.txt	2000-12-04 01:48:18.000000000 +0000
+++ linux-bk/Documentation/initrd.txt	2002-11-22 15:35:32.000000000 +0000
@@ -115,8 +115,12 @@
  1) make sure loopback block devices are configured into the kernel
  2) create an empty file system of the appropriate size, e.g.
     # dd if=/dev/zero of=initrd bs=300k count=1
-    # mke2fs -F -m0 initrd
+    # mke2fs -F -m0 -b 1024 initrd
     (if space is critical, you may want to use the Minix FS instead of Ext2)
+    (Note that due to a problem elsewhere in the kernel, you _must_ use a
+     1024-byte blocksize when creating your file system.  If any other
+     value is used, the kernel will be unable to mount the initrd at boot
+     time, causing a kernel panic.)
  3) mount the file system, e.g.
     # mount -t ext2 -o loop initrd /mnt
  4) create the console device (not necessary if using devfs, but it can't
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/isapnp.txt linux-bk/Documentation/isapnp.txt
--- linux-2.4.19/Documentation/isapnp.txt	2001-04-18 18:49:11.000000000 +0000
+++ linux-bk/Documentation/isapnp.txt	2002-11-22 15:35:34.000000000 +0000
@@ -29,6 +29,7 @@
 poke <reg> <value>	- poke configuration byte to selected register
 pokew <reg> <value>	- poke configuration word to selected register
 poked <reg> <value>	- poke configuration dword to selected register
+allow_dma0 <value>	- allow dma channel 0 during auto activation: 0=off, 1=on
 
 Explanation:
 	- variable <idx> begins with zero
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/isdn/README.HiSax linux-bk/Documentation/isdn/README.HiSax
--- linux-2.4.19/Documentation/isdn/README.HiSax	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/isdn/README.HiSax	2002-11-22 15:35:24.000000000 +0000
@@ -41,9 +41,10 @@
 ELSA Quickstep 3000PCI
 ELSA PCMCIA
 ITK ix1-micro Rev.2
-Eicon.Diehl Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
-Eicon.Diehl Diva 2.01 ISA and PCI
-Eicon.Diehl Diva Piccola
+Eicon Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
+Eicon Diva 2.01 ISA and PCI
+Eicon Diva 2.02 PCI
+Eicon Diva Piccola
 ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D)
 Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter)
 PCBIT-DP (OEM version of ASUSCOM NETWORK INC. ISDNLink)
@@ -67,13 +68,14 @@
 HFC-PCI based cards
 Winbond W6692 based cards
 HFC-S+, HFC-SP/PCMCIA cards
+formula-n enternow
+Gerdes Power ISDN
 
 Note: PCF, PCF-Pro: up to now, only the ISDN part is supported
       PCC-8: not tested yet
       Eicon.Diehl Diva U interface not tested
 
 If you know other passive cards with the Siemens chipset, please let me know.
-To use the PNP cards you need the isapnptools.
 You can combine any card, if there is no conflict between the resources
 (io, mem, irq).
 
@@ -89,8 +91,15 @@
 modules. It is included in the normal "make [menu]config" target at the
 kernel. Don't forget it, especially to select the right D-channel protocol.
 
-Please note: All PnP cards need to be configured with isapnp and will work
-only with the HiSax driver used as a module.
+Please note: In older versions of the HiSax driver, all PnP cards
+needed to be configured with isapnp and worked only with the HiSax
+driver used as a module.
+
+In the current version, HiSax will automatically use the in-kernel
+ISAPnP support, provided you selected it during kernel configuration
+(CONFIG_ISAPNP), if you don't give the io=, irq= command line parameters.
+
+The affected card types are: 4,7,12,14,19,27-30
 
 a) when built as a module
 -------------------------
@@ -191,6 +200,8 @@
    37	HFC 2BDS0 S+, SP         irq,io 
    38	NETspider U PCI card     none
    39	HFC 2BDS0 SP/PCMCIA      irq,io (set with cardmgr)
+   40   hotplug interface
+   41   Formula-n enter:now PCI  none
 
 At the moment IRQ sharing is only possible with PCI cards. Please make sure
 that your IRQ is free and enabled for ISA use.
@@ -216,6 +227,13 @@
                    (IO 1 (BASE 0x0180))
    modprobe hisax type=4 protocol=2 irq=10 io0=0x580 io1=0x180
 
+   In the current version of HiSax, you can instead simply use
+
+   modprobe hisax type=4 protocol=2
+
+   if you configured your kernel for ISAPnP. Don't run isapnp in
+   this case!
+
 6. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 12 and
    Teles 16.0, 1TR6, IRQ 5, Memory d0000 hex
    modprobe hisax type=3,1 protocol=2,1 io=0x280 mem=0,0xd0000
@@ -296,7 +314,9 @@
    36	W6692 based PCI cards   none
    37	HFC 2BDS0 S+,SP/PCMCIA  ONLY WORKS AS A MODULE !
    38	NETspider U PCI card    none
-
+   39	HFC 2BDS0 SP/PCMCIA     ONLY WORKS AS A MODULE !
+   40   hotplug interface	ONLY WORKS AS A MODULE !
+   41   Formula-n enter:now PCI none
 
 Running the driver
 ------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/kbuild/makefiles.txt linux-bk/Documentation/kbuild/makefiles.txt
--- linux-2.4.19/Documentation/kbuild/makefiles.txt	2001-02-13 22:13:42.000000000 +0000
+++ linux-bk/Documentation/kbuild/makefiles.txt	2002-11-22 15:35:32.000000000 +0000
@@ -20,9 +20,8 @@
   6  The structure of a subdirectory Makefile
      6.1  Comments
      6.2  Goal definitions
-     6.3  Adapter section
-     6.4  Rules.make section
-     6.5  Special rules
+     6.3  Rules.make section
+     6.4  Special rules
   7  Rules.make variables
      7.1  Subdirectories
      7.2  Object file goals
@@ -34,8 +33,7 @@
   8  New-style variables
      8.1  New variables
      8.2  Converting to old-style
-  9  Compatibility with Linux Kernel 2.2
- 10  Credits
+  9  Credits
 
 
 === 1 Overview
@@ -100,15 +98,15 @@
 
 === 3 Makefile language
 
-The kernel Makefiles are designed to run with Gnu Make.  The Makefiles
-use only the documented features of Gnu Make, but they do use many
-Gnu extensions.
+The kernel Makefiles are designed to run with GNU Make.  The Makefiles
+use only the documented features of GNU Make, but they do use many
+GNU extensions.
 
-Gnu Make supports elementary list-processing functions.  The kernel
+GNU Make supports elementary list-processing functions.  The kernel
 Makefiles use a novel style of list building and manipulation with few
 "if" statements.
 
-Gnu Make has two assignment operators, ":=" and "=".  ":=" performs
+GNU Make has two assignment operators, ":=" and "=".  ":=" performs
 immediate evaluation of the right-hand side and stores an actual string
 into the left-hand side.  "=" is like a formula definition; it stores the
 right-hand side in an unevaluated form and then evaluates this form each
@@ -192,7 +190,7 @@
 	$(DRIVERS), and $(LIBS).  The arch Makefile defines $(HEAD)
 	and $(LINKFLAGS), and extends $(CORE_FILES) and $(LIBS).
 
-	Note: there are more names here than necessary.  $(NETWORKS),
+	Note: there are more variables here than necessary.  $(NETWORKS),
 	$(DRIVERS), and even $(LIBS) could be subsumed into $(CORE_FILES).
 
     CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP
@@ -290,12 +288,12 @@
 
     MAKE, MAKEFILES
 
-	Some variables internal to Gnu Make.
+	Some variables internal to GNU Make.
 
 	$(MAKEFILES) in particular is used to force the arch Makefiles
 	and subdirectory Makefiles to read $(TOPDIR)/.config without
-	including it explicitly.  (This was an implementation hack and
-	could be fixed).
+	including it explicitly.  (This was an implementational hack
+	and could be fixed).
 
 
 
@@ -339,7 +337,7 @@
 	extends them.
 
 	Many arch Makefiles dynamically run the target C compiler to
-	probe what options it supports:
+	probe supported options:
 
 		# arch/i386/Makefile
 
@@ -376,7 +374,7 @@
 
 --- 5.2 Vmlinux build variables
 
-An arch Makefile co-operates with the top Makefile to define variables
+An arch Makefile cooperates with the top Makefile to define variables
 which specify how to build the vmlinux file.  Note that there is no
 corresponding arch-specific section for modules; the module-building
 machinery is all architecture-independent.
@@ -466,17 +464,15 @@
 
 === 6 The structure of a subdirectory Makefile
 
-A subdirectory Makefile has five sections.
+A subdirectory Makefile has four sections.
 
 
 
 --- 6.1 Comments
 
-The first section is a comment header.  Just write what you would
-write if you were editing a C source file, but use "# ..." instead of
-"/* ... */".  Historically, many anonymous people have edited kernel
-Makefiles without leaving any change histories in the header; comments
-from them would have been valuable.
+The first section is a comment header. Historically, many anonymous
+people have edited kernel Makefiles without leaving any change
+histories in the header; comments from them would have been valuable.
 
 
 
@@ -488,20 +484,7 @@
 entered.  The declarations in these lines depend heavily on the kernel
 configuration variables (CONFIG_* symbols).
 
-In some Makefiles ("old-style Makefiles"), the second section looks
-like this:
-
-	# drivers/parport/Makefile
-	ifeq ($(CONFIG_PARPORT_PC),y)
-	  LX_OBJS += parport_pc.o
-	else
-	  ifeq ($(CONFIG_PARPORT_PC),m)
-	    MX_OBJS += parport_pc.o
-	  endif
-	endif
-
-In most Makefiles ("new-style Makefiles"), the second section looks
-like this:
+The second section looks like this:
 
 	# drivers/block/Makefile
 	obj-$(CONFIG_MAC_FLOPPY)	+= swim3.o
@@ -509,35 +492,18 @@
 	obj-$(CONFIG_AMIGA_FLOPPY)	+= amiflop.o
 	obj-$(CONFIG_ATARI_FLOPPY)	+= ataflop.o
 
-The new-style Makefiles are more compact and easier to get correct
-for certain features (such as CONFIG_* options that enable more than
-one file).  If you have a choice, please write a new-style Makefile.
-
-
-
---- 6.3 Adapter section
 
-The third section is an adapter section.  In old-style Makefiles, this
-third section is not present.  In new-style Makefiles, the third section
-contains boilerplate code which converts from new-style variables to
-old-style variables.  This is because Rules.make processes only the
-old-style variables.
+--- 6.3 Rules.make section
 
-See section 8.2 ("Converting to old-style") for examples.
-
-
-
---- 6.4 Rules.make section
-
-The fourth section is the single line:
+The third section is the single line:
 
 	include $(TOPDIR)/Rules.make
 
 
 
---- 6.5 Special rules
+--- 6.4 Special rules
 
-The fifth section contains any special Makefile rules needed that are
+The fourth section contains any special Makefile rules needed that are
 not available through the common rules in Rules.make.
 
 
@@ -550,352 +516,166 @@
 
 --- 7.1 Subdirectories
 
-    ALL_SUB_DIRS, SUB_DIRS, MOD_IN_SUB_DIRS, MOD_SUB_DIRS
+A Makefile is only responsible for building objects in its own
+directory. Files in subdirectories should be taken care of by
+Makefiles in the these subdirs. The build system will automatically
+invoke make recursively in subdirectories, provided you let it know of
+them.
 
-	$(ALL_SUB_DIRS) is an unconditional list of *all* the
-	subdirectories in a given directory.  This list should not depend
-	on the kernel configuration.
-
-	$(SUB_DIRS) is a list of subdirectories which may contribute code
-	to vmlinux.  This list may depend on the kernel configuration.
-
-	$(MOD_SUB_DIRS) and $(MOD_IN_SUB_DIRS) are lists of subdirectories
-	which may build kernel modules.  Both names have exactly the
-	same meaning.  (In version 2.2 and earlier kernels, these
-	variables had different meanings -- hence the different names).
+To do so, use the subdir-{y,m,n,} variables:
 
-	For new code, $(MOD_SUB_DIRS) is recommended and $(MOD_IN_SUB_DIRS)
-	is deprecated.
+	subdir-$(CONFIG_ISDN)                   += i4l
+	subdir-$(CONFIG_ISDN_CAPI)              += capi
 
-	Example:
+When building the actual kernel, i.e. vmlinux ("make
+{vmlinux,bzImage,...}"), make will recursively descend into
+directories listed in $(subdir-y).
 
-		# fs/Makefile
-		ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs \
-			       umsdos ntfs hpfs sysv smbfs ncpfs ufs efs affs \
-			       romfs autofs hfs lockd nfsd nls devpts devfs \
-			       adfs partitions qnx4 udf bfs cramfs openpromfs \
-			       autofs4 ramfs jffs
-		SUB_DIRS :=
+When building modules ("make modules"), make will recursively descend
+into directories listed in $(subdir-m).
 
-		...
+When building the dependencies ("make dep") make needs to visit every
+subdir, so it'll descend into every directory listed in 
+$(subdir-y), $(subdir-m), $(subdir-n), $(subdir-).
 
-		ifeq ($(CONFIG_EXT2_FS),y)
-		SUB_DIRS += ext2
-		else
-		  ifeq ($(CONFIG_EXT2_FS),m)
-		  MOD_SUB_DIRS += ext2
-		  endif
-		endif
+You may encounter the case where a config option may be set to "y", but
+you still want to possibly build modules in that subdirectory.
 
-		ifeq ($(CONFIG_CRAMFS),y)
-		SUB_DIRS += cramfs
-		else
-		  ifeq ($(CONFIG_CRAMFS),m)
-		  MOD_SUB_DIRS += cramfs
-		  endif
-		endif
-
-	Example:
+For example, drivers/isdn/capi/Makefile has
 
-		# drivers/net/Makefile
-		SUB_DIRS     := 
-		MOD_SUB_DIRS :=
-		MOD_IN_SUB_DIRS :=
-		ALL_SUB_DIRS := $(SUB_DIRS) fc hamradio irda pcmcia tokenring \
-				wan sk98lin arcnet skfp tulip appletalk
+	obj-$(CONFIG_ISDN_CAPI)                 += kernelcapi.o capiutil.o
+	obj-$(CONFIG_ISDN_CAPI_CAPI20)          += capi.o
 
-		...
+where it's possible that CONFIG_ISDN_CAPI=y, but
+CONFIG_ISDN_CAPI_CAPI20=m.
 
-		ifeq ($(CONFIG_IRDA),y)
-		SUB_DIRS += irda
-		MOD_IN_SUB_DIRS += irda
-		else
-		  ifeq ($(CONFIG_IRDA),m)
-		  MOD_IN_SUB_DIRS += irda
-		  endif
-		endif
+This is expressed by the following construct in the parent Makefile
+drivers/isdn/Makefile:
 
-		ifeq ($(CONFIG_TR),y)
-		SUB_DIRS += tokenring
-		MOD_IN_SUB_DIRS += tokenring
-		else
-		  ifeq ($(CONFIG_TR),m)
-		  MOD_IN_SUB_DIRS += tokenring
-		  endif
-		endif
+	mod-subdirs                             := i4l hisax capi eicon
+	subdir-$(CONFIG_ISDN_CAPI)              += capi
 
+Having a subdir ("capi") listed in the variable $(mod-subdirs) will
+make the build system enter the specified subdirectory during "make
+modules" also, even though the subdir ("capi") is listed only in
+$(subdir-y), not $(subdir-m).
 
 
 --- 7.2 Object file goals
 
-    O_TARGET, O_OBJS, OX_OBJS
+    O_TARGET, obj-y
 
-	The subdirectory Makefile specifies object files for vmlinux in
-	the lists $(O_OBJS) and $(OX_OBJS).  These lists depend on the
-	kernel configuration.
-
-	The "X" in "OX_OBJS" stands for "eXport".  Files in $(OX_OBJS)
-	may use the EXPORT_SYMBOL macro to define public symbols which
-	loadable kernel modules can see.  Files in $(O_OBJS) may not use
-	EXPORT_SYMBOL (and you will get a funky error message if you try).
-
-	[Yes, it's kludgy to do this by hand.  Yes, you can define all
-	your objects as $(OX_OBJS) whether they define symbols or not;
-	but then you will notice a lot of extra compiles when you edit
-	any source file.  Blame CONFIG_MODVERSIONS for this.]
-
-	Data that is passed to other objects via registration functions
-	(e.g. pci_register_driver, pm_register) does not need to be marked
-	as EXPORT_SYMBOL.  The objects that pass data via registration
-	functions do not need to be marked as OX_OBJS, unless they also have
-	exported symbols.
-
-	Rules.make compiles all the $(O_OBJS) and $(OX_OBJS) files.
-	It then calls "$(LD) -r" to merge these files into one .o file
-	with the name $(O_TARGET).  This $(O_TARGET) name also appears
-	in the top Makefile.
-
-	The order of files in $(O_OBJS) and $(OX_OBJS) is significant.
-	All $(OX_OBJS) files come first, in the order listed, followed by
-	all $(O_OBJS) files, in the order listed.  Duplicates in the lists
-	are allowed: the first instance will be linked into $(O_TARGET)
-	and succeeding instances will be ignored.  (Note: Rules.make may
-	emit warning messages for duplicates, but this is harmless).
+	The subdirectory Makefile specifies object files for vmlinux
+	in the lists $(obj-y).  These lists depend on the kernel
+	configuration.
 
-	Example:
+	Rules.make compiles all the $(obj-y) files.  It then calls
+	"$(LD) -r" to merge these files into one .o file with the name
+	$(O_TARGET).  This $(O_TARGET) is later linked into vmlinux by 
+	a parent Makefile.
 
-		# arch/alpha/kernel/Makefile
-		O_TARGET := kernel.o
-		O_OBJS   := entry.o traps.o process.o osf_sys.o irq.o \
-			    irq_alpha.o signal.o setup.o ptrace.o time.o \
-			    semaphore.o
-		OX_OBJS  := alpha_ksyms.o
+	The order of files in $(obj-y) is significant.  Duplicates in
+	the lists are allowed: the first instance will be linked into
+	$(O_TARGET) and succeeding instances will be ignored.
 
-		ifdef CONFIG_SMP
-		O_OBJS   += smp.o irq_smp.o
-		endif
+	Link order is significant, because certain functions
+	(module_init() / __initcall) will be called during boot in the
+	order they appear. So keep in mind that changing the link
+	order may e.g.  change the order in which your SCSI
+	controllers are detected, and thus you disks are renumbered.
 
-		ifdef CONFIG_PCI
-		O_OBJS   += pci.o pci_iommu.o
-		endif
-
-	Even if a subdirectory Makefile has an $(O_TARGET), the .config
-	options still control whether or not its $(O_TARGET) goes into
-	vmlinux.  See the $(M_OBJS) example below.
-
-	Sometimes the ordering of all $(OX_OBJS) files before all
-	$(O_OBJS) files can be a problem, particularly if both
-	$(O_OBJS) files and $(OX_OBJS) files contain __initcall
-	declarations where order is important.   To avoid this imposed
-	ordering, the use of $(OX_OBJS) can be dropped altogether and
-	$(MIX_OBJS) used instead.
-
-	If this approach is used, then:
-	 - All objects to be linked into vmlinux should be listed in
-	   $(O_OBJS) in the desired order.
-	 - All objects to be created as modules should be listed in
-	   $(M_OBJS)
-	 - All objects that export symbols should also be listed in
-	   $(MIX_OBJS).
-
-	This has the same effect as maintaining the
-	exported/non-exported split, except that there is more control
-	over the ordering of object files in vmlinux.
-	
+	Example:
 
+	    # Makefile for the kernel ISDN subsystem and device drivers.
 
---- 7.3 Library file goals
+	    # The target object and module list name.
 
-    L_TARGET, L_OBJS, LX_OBJS
+	    O_TARGET        := vmlinux-obj.o
 
-	These names are similar to the O_* names.  Once again, $(L_OBJS)
-	and $(LX_OBJS) specify object files for the resident kernel;
-	once again, the lists depend on the current configuration; and
-	once again, the files that call EXPORT_SYMBOL go on the "X" list.
-
-	The difference is that "L" stands for "Library".  After making
-	$(L_OBJS) and $(LX_OBJS), Rules.make uses the "$(AR) rcs" command
-	to put these files into an archive file (a library) with the
-	name $(L_TARGET).  This name also appears in the top Makefile.
+	    # Each configuration option enables a list of files.
 
-	Example:
+	    obj-$(CONFIG_ISDN)                      += isdn.o
+	    obj-$(CONFIG_ISDN_PPP_BSDCOMP)          += isdn_bsdcomp.o
 
-		# arch/i386/lib/Makefile
-		L_TARGET = lib.a
-		L_OBJS  = checksum.o old-checksum.o delay.o \
-			usercopy.o getuser.o putuser.o iodebug.o
+	    # The global Rules.make.
 
-		ifdef CONFIG_X86_USE_3DNOW
-		L_OBJS += mmx.o
-		endif
+	    include $(TOPDIR)/Rules.make
 
-		ifdef CONFIG_HAVE_DEC_LOCK
-		L_OBJS += dec_and_lock.o
-		endif
+--- 7.3 Library file goals
 
-	The order of files in $(L_OBJS) and $(LX_OBJS) is not significant.
-	Duplicates in the lists are allowed.  (Note: Rules.make may emit
-	warning messages for duplicates, but this is harmless).
-
-	A subdirectory Makefile can specify either an $(O_TARGET),
-	an $(L_TARGET), or both.  Here is a discussion of the differences.
-
-	All of the files in an $(O_TARGET) are guaranteed to appear in
-	the resident vmlinux image.  In an $(L_TARGET), only the files
-	that satisfy undefined symbol references from other files will
-	appear in vmlinux.
-
-	In a conventional link process, the linker processes some
-	object files and creates a list of unresolved external symbols.
-	The linker then looks in a set of libraries to resolve these
-	symbols.  Indeed, the Linux kernel used to be linked this way,
-	with the bulk of the code stored in libraries.
-
-	But vmlinux contains two types of object files that cannot be
-	fetched out of libraries this way:
-
-	    (1) object files that are purely EXPORT_SYMBOL definitions
-	    (2) object files that use module_init or __initcall initializers
-		(instead of an initialization routine called externally)
-
-	These files contain autonomous initializer sections which provide
-	code and data without being explicitly called.	If these files
-	were stored in $(L_TARGET) libraries, the linker would fail
-	to include them in vmlinux.  Thus, most subdirectory Makefiles
-	specify an $(O_TARGET) and do not use $(L_TARGET).
-
-	Other considerations: $(O_TARGET) leads to faster re-link times
-	during development activity, but $(L_TARGET) gives better error
-	messages for unresolved symbols.
+    L_TARGET
 
+	Instead of building an O_TARGET object file, you may also
+	build an archive which again contains objects listed in
+	$(obj-y). This is normally not necessary and only used in
+	the lib, arch/$(ARCH)/lib directories.
 
 
 --- 7.4 Loadable module goals
 
-    M_OBJS, MX_OBJS
+    obj-m
 
-	$(M_OBJS) and $(MX_OBJS) specify object files which are built
-	as loadable kernel modules.  As usual, the "X" in $(MX_OBJS)
-	stands for "eXport"; source files that use EXPORT_SYMBOL must
-	appear on an $(MX_OBJS) list.
+	$(obj-m) specify object files which are built as loadable
+	kernel modules.
 
 	A module may be built from one source file or several source
-	files.	In the case of one source file, the subdirectory
-	Makefile simply adds the file to either $(M_OBJS) or $(MX_OBJS),
-	as appropriate.
+	files. In the case of one source file, the subdirectory
+	Makefile simply adds the file to $(obj-m)
 
 	Example:
 
-		# drivers/net/irda/Makefile
-		ifeq ($(CONFIG_IRTTY_SIR),y)
-		L_OBJS += irtty.o
-		else
-		  ifeq ($(CONFIG_IRTTY_SIR),m)
-		  M_OBJS += irtty.o
-		  endif
-		endif
+	    obj-$(CONFIG_ISDN_PPP_BSDCOMP)          += isdn_bsdcomp.o
 
-		ifeq ($(CONFIG_IRPORT_SIR),y)
-		LX_OBJS += irport.o
-		else
-		  ifeq ($(CONFIG_IRPORT_SIR),m)
-		  MX_OBJS += irport.o
-		  endif
-		endif
+	If a kernel module is built from several source files, you specify
+	that you want to build a module in the same way as above.
 
-	If a kernel module is built from several source files, there
-	are two ways to specify the set of source files.  One way is to
-	build a single module for the entire subdirectory.  This way is
-	popular in the file system and network protocol stacks.
+	However, the build system of course needs to know which the parts
+	are that you want to build your module of, so you have to tell it
+	by setting an $(<module_name>-objs) variable.
 
 	Example:
 
-		# fs/ext2/Makefile
-		O_TARGET := ext2.o
-		O_OBJS   := acl.o balloc.o bitmap.o dir.o file.o fsync.o \
-			    ialloc.o inode.o ioctl.o namei.o super.o symlink.o \
-			    truncate.o
-		M_OBJS   := $(O_TARGET)
-
-	In this example, the module name will be ext2.o.  Because this
-	file has the same name has $(O_TARGET), Rules.make will use
-	the $(O_TARGET) rule to build ext2.o: it will run "$(LD) -r"
-	on the list of $(O_OBJS) files.
-
-	Note that this subdirectory Makefile defines both an $(O_TARGET)
-	and an $(M_OBJS).  The control code, up in fs/Makefile, will
-	select between these two.  If CONFIG_EXT2_FS=y, then fs/Makefile
-	will build $(O_TARGET); and if CONFIG_EXT_FS=m, then fs/Makefile
-	will build $(M_OBJS) instead.  (Yes, this is a little delicate
-	and a little confusing).
+	    obj-$(CONFIG_ISDN)                      += isdn.o
+
+	    isdn-objs := isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o
+
+	In this example, the module name will be isdn.o. Rules.make
+	will compile the objects listed in $(isdn-objs) and then run
+	"$(LD) -r" on the list of these files to generate isdn.o
+
+	Note: Of course, when you are building objects into the kernel,
+	the syntax above will also work. So, if you have CONFIG_ISDN=y,
+	the build system will build an isdn.o for you out of the individual
+	parts and then link this into the $(O_TARGET), as you'd expect.
+
 
+--- 7.5 Objects which export symbols
 
+    export-objs
+
+	When using loadable modules, not every global symbol in the
+	kernel / other modules is automatically available, only those
+	explicitly exported are available for your module.
 
---- 7.5 Multi-part modules
-
-    MI_OBJS, MIX_OBJS
-
-	Some kernel modules are composed of several object files
-	linked together, but do not include every object file in their
-	subdirectory.  $(MI_OBJS) and $(MIX_OBJS) are for this case.
-
-	"M" stands for Module.
-	"I" stands for Intermediate.
-	"X", as usual, stands for "eXport symbol".
+	To make a symbol available for use in modules, to "export" it,
+	use the EXPORT_SYMBOL(<symbol>) directive in your source. In
+	addition, you need to list all object files which export symbols
+	(i.e. their source contains an EXPORT_SYMBOL() directive) in the
+	Makefile variable $(export-objs).
 
 	Example:
 
-		# drivers/sound/Makefile
-		gus-objs  := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
-		pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
-		sb-objs	  := sb_card.o
-
-		gus.o: $(gus-objs)
-			$(LD) -r -o $@ $(gus-objs)
-
-		pas2.o: $(pas2-objs)
-			$(LD) -r -o $@ $(pas2-objs)
-
-		sb.o: $(sb-objs)
-			$(LD) -r -o $@ $(sb-objs)
-
-	The kernel modules gus.o, pas2.o, and sb.o are the *composite
-	files*.  The object files gus_card.o, gus_midi.o, gus_vol.o,
-	gus_wave.o, ics2101.o, pas2_card.o, pas2_midi.o, pas2_mixer.o,
-	pas2_pcm.o, and sb_card.o are *component files*.  The component
-	files are also called *intermediate files*.
-
-	In another part of drivers/sound/Makefile (not shown), all of
-	the component files are split out.  For the resident drivers:
-	the component object files go onto $(O_OBJS) and $(OX_OBJS)
-	lists, depending on whether they export symbols or not; and the
-	composite files are never built.  For the kernel modules: the
-	component object files go onto $(MI_OBJS) and $(MIX_OBJS);
-	the composite files go onto $(M_OBJS).
-
-	The subdirectory Makefile must also specify the linking rule
-	for a multi-object-file module:
-
-		# drivers/sound/Makefile
-
-		gus.o: $(gus-objs)
-			$(LD) -r -o $@ $(gus-objs)
-
-		pas2.o: $(pas2-objs)
-			$(LD) -r -o $@ $(pas2-objs)
-
-		sb.o: $(sb-objs)
-			$(LD) -r -o $@ $(sb-objs)
-
-
-	As is mentioned in section 7.2 ("Object file goals"),
-	$(MIX_OBJS) can also be used simply to list all objects that
-	export any symbols.  If this approach is taken, then
-	$(O_OBJS), $(L_OBJS), $(M_OBJS) and $(MI_OBJS) should simply
-	lists all of the vmlinux object files, library object files,
-	module object files and intermediate module files
-	respectively.  Duplication between $(MI_OBJS) and $(MIX_OBJS)
-	is not a problem.
+	    # Objects that export symbols.
+
+	    export-objs     := isdn_common.o
+
+	since isdn_common.c contains
+
+	    EXPORT_SYMBOL(register_isdn);
+
+	which makes the function register_isdn available to
+	low-level ISDN drivers.
+	    
 
 --- 7.6 Compilation flags
 
@@ -1013,6 +793,10 @@
 
 === 8 New-style variables
 
+[ This sections dates back from a time where the way to write Makefiles
+  described above was "new-style". I'm leaving it in as it describes the
+  same thing in other words, so it may be of some use ]
+
 The "new-style variables" are simpler and more powerful than the
 "old-style variables".  As a result, many subdirectory Makefiles shrank
 more than 60%.  This author hopes that, in time, all arch Makefiles and
@@ -1040,7 +824,7 @@
 		obj-$(CONFIG_ATARI_FLOPPY)      += ataflop.o
 
 	Notice the use of $(CONFIG_...) substitutions on the left hand
-	side of an assignment operator.  This gives Gnu Make the power
+	side of an assignment operator.  This gives GNU Make the power
 	of associative indexing!  Each of these assignments replaces
 	eight lines of code in an old-style Makefile.
 
@@ -1053,9 +837,8 @@
 	$(obj-n) and $(obj-) are ignored.
 
 	Each list may contain duplicates items; duplicates are
-	automatically removed later.  Also, if a file appears in both
-	$(obj-y) and $(obj-m), it will automatically be removed from
-	the $(obj-m) list.
+	automatically removed later.  Duplicates in both $(obj-y) and
+	$(obj-m) will automatically be removed from the $(obj-m) list.
 
 	Example:
 
@@ -1099,16 +882,14 @@
 	$(export-objs) list in a new-style Makefile is simpler and easier
 	to audit.
 
-    list-multi
     $(foo)-objs
 
 	Some kernel modules are composed of multiple object files linked
-	together.  $(list-multi) is a list of such kernel modules.
-	This is a static list; it does not depend on the configuration.
+	together.
 
-	For each kernel module in $(list-multi) there is another list
-	of all the object files which make up that module.  For a kernel
-	module named foo.o, its object file list is foo-objs.
+	For each multi-part kernel modul there is a list of all the
+	object files which make up that module.  For a kernel module
+	named foo.o, its object file list is foo-objs.
 
 	Example:
 
@@ -1135,44 +916,16 @@
 		obj-$(CONFIG_SCSI_INIA100)	+= a100u2w.o
 
 	Suppose that CONFIG_SCSI=y.  Then vmlinux needs to link in all
-	14 components of scsi_mod.o, so these components will go onto
-	$(O_OBJS) and $(OX_OBJS).  The composite file scsi_mod.o will
-	never be created.  The boilerplate conversion code produces this
-	result with a few lines of list processing commands.
+	14 components of scsi_mod.o.
 
 	Suppose that CONFIG_BLK_DEV_SR=m.  Then the 3 components
-	of sr_mod.o will linked together with "$(LD) -r" to make the
-	kernel module sr_mod.o, so these 3 components need to go onto
-	the $(MI_OBJS) and $(MIX_OBJS) lists; the composite file sr_mod.o
-	goes onto $(M_OBJS).  The boilerplate conversion code takes care
-	of this, too.
-
-	And suppose CONFIG_SCSI_INITIO=n.  Then initio.o goes onto the
-	$(obj-n) list and that's the end of it.  Its component files
-	are not compiled, and the composite file is not created.
+	of sr_mod.o will be linked together with "$(LD) -r" to make the
+	kernel module sr_mod.o.
 
-	Finally, the subdirectory Makefile needs to define rules to
-	build each multi-object kernel module from its component list.
-	Example:
-
-		# drivers/scsi/Makefile
+	Also suppose CONFIG_SCSI_INITIO=n.  Then initio.o goes onto
+	the $(obj-n) list and that's the end of it.  Its component
+	files are not compiled, and the composite file is not created.
 
-		scsi_mod.o: $(scsi_mod-objs)
-			$(LD) -r -o $@ $(scsi_mod-objs)
-
-		sr_mod.o: $(sr_mod-objs)
-			$(LD) -r -o $@ $(sr_mod-objs)
-
-		initio.o: $(initio-objs)
-			$(LD) -r -o $@ $(initio-objs)
-
-		a100u2w.o: $(a100u2w-objs)
-			$(LD) -r -o $@ $(a100u2w-objs)
-
-	These rules are very regular; it would be nice for the boilerplate
-	code or Rules.make to synthesize these rules automatically.
-	But until that happens, the subdirectory Makefile needs to define
-	these rules explicitly.
 
     subdir-y subdir-m subdir-n subdir-
 
@@ -1190,9 +943,9 @@
 	These variables work similar to obj-*, but are used for
 	subdirectories instead of object files.
 
-	After executing all of the assignments, the subdirectory
-	Makefile has built up four lists: $(subdir-y), $(subdir-m),
-	$(subdir-n), and $(subdir-).
+	After executing all assignments, the subdirectory Makefile has
+	built up four lists: $(subdir-y), $(subdir-m), $(subdir-n),
+	and $(subdir-).
 
 	$(subdir-y) is a list of directories that should be entered
 		for making vmlinux.
@@ -1217,72 +970,7 @@
 	This means nls should be added to (subdir-y) and $(subdir-m) if
 	CONFIG_NFS = y.
 
---- 8.2 Converting to old-style
-
-	The following example is taken from drivers/usb/Makefile.
-	Note that this uses MIX_OBJS to avoid the need for OX_OBJS and
-	MX_OBJS and thus to maintain the ordering of objects in $(obj-y)
-
-		# Translate to Rules.make lists.
-		multi-used	:= $(filter $(list-multi), $(obj-y) $(obj-m))
-		multi-objs	:= $(foreach m, $(multi-used), $($(basename $(m))-objs))
-		active-objs	:= $(sort $(multi-objs) $(obj-y) $(obj-m))
-
-		O_OBJS		:= $(obj-y)
-		M_OBJS		:= $(obj-m)
-		MIX_OBJS	:= $(filter $(export-objs), $(active-objs))
-
-	An example for libraries from drivers/acorn/scsi/Makefile:
-
-		# Translate to Rules.make lists.
-
-		L_OBJS		:= $(filter-out $(export-objs), $(obj-y))
-		LX_OBJS		:= $(filter     $(export-objs), $(obj-y))
-		M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
-		MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
-
-	As ordering is not so important in libraries, this still uses
-	LX_OBJS and MX_OBJS, though (presumably) it could be changed to
-	use MIX_OBJS as follows:
-
-		active-objs	:= $(sort $(obj-y) $(obj-m))
-		L_OBJS		:= $(obj-y)
-		M_OBJS		:= $(obj-m)
-		MIX_OBJS	:= $(filter $(export-objs), $(active-objs))
-		
-
-	which is clearly shorted and arguably clearer.
-
-=== 9 Compatibility with Linux Kernel 2.2
-
-Most of the information in this document also applies to 2.2, although
-there is no indication of which things have changed when.  Here are some
-hints for writing subdirectory Makefiles that are compatible with Linux
-kernel 2.2.
-
-You can write either an old-style Makefile or a new-style Makefile
-with a boilerplate adapter section.  See the 2.2 version of
-drivers/sound/Makefile for a copy of the boilerplate code.
-
-In 2.2, Rules.make makes a distinction between $(MOD_SUB_DIRS)
-and $(MOD_IN_SUB_DIRS).  If you have a single directory with no
-subdirectories, this will not matter to you.  If you have a whole
-tree, then you need to know the difference between $(MOD_SUB_DIRS)
-and $(MOD_IN_SUB_DIRS).  For example code: $(MOD_SUB_DIRS) is used
-extensively in fs/Makefile; $(MOD_IN_SUB_DIRS) is used extensively in
-drivers/net/Makefile.
-
-If you are already using MOD_LIST_NAME, go ahead and keep using it.
-If you don't already have a MOD_LIST_NAME, go ahead and keep not using
-one; your module will be a 'misc' module in 2.2.
-
-Assembly language rules were a mess in 2.2.  If you have assembly language
-files, this author recommends that you write your own explicit rules
-for each file by name.
-
-
-
-=== 10 Credits
+=== 9 Credits
 
 Thanks to the members of the linux-kbuild mailing list for reviewing
 drafts of this document, with particular thanks to Peter Samuelson
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/kernel-parameters.txt linux-bk/Documentation/kernel-parameters.txt
--- linux-2.4.19/Documentation/kernel-parameters.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/kernel-parameters.txt	2002-11-22 15:35:31.000000000 +0000
@@ -23,6 +23,7 @@
 	HW	Appropriate hardware is enabled.
 	IA-32	IA-32 aka i386 architecture is enabled.
 	IA-64	IA-64 architecture is enabled.
+	IP_PNP	IP DCHP, BOOTP, or RARP is enabled.
 	ISAPNP  ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY 	Appropriate joystick support is enabled.
@@ -251,7 +252,7 @@
 
 	initrd=		[BOOT] Specify the location of the initial ramdisk. 
 
-	ip=		[PNP]
+	ip=		[IP_PNP]
 
 	isapnp=		[ISAPNP] Specify RDP, reset, pci_scan and verbosity.
 
@@ -273,10 +274,14 @@
  
 	kbd-reset	[VT]
 
-	keep_initrd	[HW, ARM]
+	keepinitrd	[HW, ARM]
 
 	load_ramdisk=	[RAM] List of ramdisks to load from floppy.
 
+	lockd.udpport=	[NFS]
+
+	lockd.tcpport=	[NFS]
+
 	logi_busmouse=	[HW, MOUSE]
 
 	lp=0		[LP]	Specify parallel ports to use, e.g,
@@ -313,7 +318,7 @@
 
 	max_scsi_luns=	[SCSI]
 
-	mca-pentium	[BUGS=ix86]
+	mca-pentium	[BUGS=IA-32]
 
 	mcd=		[HW,CD]
 
@@ -327,6 +332,11 @@
 
 	megaraid=	[HW,SCSI]
  
+	mem=exactmap	[KNL,BOOT,IA-32] enable setting of an exact
+			e820 memory map, as specified by the user.
+			Such mem=exactmap lines can be constructed
+			based on BIOS output or other requirements.
+
 	mem=nn[KMG]	[KNL,BOOT] force use of a specific amount of
 			memory; to be used when the kernel is not able
 			to see the whole system memory or for test.
@@ -359,9 +369,9 @@
 
 	nfsroot=	[NFS] nfs root filesystem for disk-less boxes.
 
-	nmi_watchdog=	[KNL,BUGS=ix86] debugging features for SMP kernels.
+	nmi_watchdog=	[KNL,BUGS=IA-32] debugging features for SMP kernels.
 
-	no387		[BUGS=ix86] Tells the kernel to use the 387 maths
+	no387		[BUGS=IA-32] Tells the kernel to use the 387 maths
 			emulation library even if a 387 maths coprocessor
 			is present.
 
@@ -379,7 +389,9 @@
 
 	nohlt		[BUGS=ARM]
  
-	no-hlt		[BUGS=ix86]
+	no-hlt		[BUGS=IA-32] Tells the kernel that the hlt
+			instruction doesn't work correctly and not to
+			use it.
 
 	noht		[SMP,IA-32] Disables P4 Xeon(tm) HyperThreading.
 
@@ -396,7 +408,7 @@
 
 	nosync		[HW, M68K] Disables sync negotiation for all devices.
 
-	notsc           [BUGS=ix86] Disable Time Stamp Counter
+	notsc           [BUGS=IA-32] Disable Time Stamp Counter
 
 	nowb		[ARM]
  
@@ -504,7 +516,7 @@
 	ramdisk_start=	[RAM] Starting block of RAM disk image (so you can
 			place it after the kernel image on a boot floppy).
 
-	reboot=		[BUGS=ix86]
+	reboot=		[BUGS=IA-32]
 
 	reserve=	[KNL,BUGS] force the kernel to ignore some iomem area.
 
@@ -514,6 +526,10 @@
 
 	root=		[KNL] root filesystem.
 
+	rootflags=	[KNL] set root filesystem mount option string
+
+	rootfstype=	[KNL] set root filesystem type
+
 	rw		[KNL] Mount root device read-write on boot.
 
 	S		[KNL] run init in single mode.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/ldm.txt linux-bk/Documentation/ldm.txt
--- linux-2.4.19/Documentation/ldm.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/ldm.txt	2002-11-22 15:35:29.000000000 +0000
@@ -0,0 +1,102 @@
+
+            LDM - Logical Disk Manager (Dynamic Disks)
+            ------------------------------------------
+
+Overview
+--------
+
+Windows 2000 and XP use a new partitioning scheme.  It is a complete
+replacement for the MSDOS style partitions.  It stores its information in a
+1MiB journalled database at the end of the physical disk.  The size of
+partitions is limited only by disk space.  The maximum number of partitions is
+nearly 2000.
+
+Any partitions created under the LDM are called "Dynamic Disks".  There are no
+longer any primary or extended partitions.  Normal MSDOS style partitions are
+now known as Basic Disks.
+
+If you wish to use Spanned, Striped, Mirrored or RAID 5 Volumes, you must use
+Dynamic Disks.  The journalling allows Windows to make changes to these
+partitions and filesystems without the need to reboot.
+
+Once the LDM driver has divided up the disk, you can use the MD driver to
+assemble any multi-partition volumes, e.g.  Stripes, RAID5.
+
+To prevent legacy applications from repartitioning the disk, the LDM creates a
+dummy MSDOS partition containing one disk-sized partition.
+
+
+Example
+-------
+
+Below we have a 50MiB disk, divided into seven partitions.
+N.B.  The missing 1MiB at the end of the disk is where the LDM database is
+      stored.
+
+  Device | Offset Bytes  Sectors  MiB | Size   Bytes  Sectors  MiB
+  -------+----------------------------+---------------------------
+  hda    |            0        0    0 |     52428800   102400   50
+  hda1   |     51380224   100352   49 |      1048576     2048    1
+  hda2   |        16384       32    0 |      6979584    13632    6
+  hda3   |      6995968    13664    6 |     10485760    20480   10
+  hda4   |     17481728    34144   16 |      4194304     8192    4
+  hda5   |     21676032    42336   20 |      5242880    10240    5
+  hda6   |     26918912    52576   25 |     10485760    20480   10
+  hda7   |     37404672    73056   35 |     13959168    27264   13
+
+The LDM Database may not store the partitions in the order that they appear on
+disk, but the driver will sort them.
+
+When Linux boots, you will see something like:
+
+Partition check:
+  hda: [LDM] hda1 hda2 hda3 hda4 hda5 hda6 hda7
+
+
+Compiling LDM Support
+---------------------
+
+To enable LDM, choose the following two options: 
+
+  "Advanced partition selection" CONFIG_PARTITION_ADVANCED
+  "Windows Logical Disk Manager (Dynamic Disk) support" CONFIG_LDM_PARTITION
+
+If you believe the driver isn't working as it should, you can enable the extra
+debugging code.  This will produce a LOT of output.  The option is:
+
+  "Windows LDM extra logging" CONFIG_LDM_DEBUG
+
+N.B. The partition code cannot be compiled as a module.
+
+As with all the partition code, if the driver doesn't see signs of its type of
+partition, it will pass control to another driver, so there is no harm in
+enabling it.
+
+If you have Dynamic Disks but don't enable the driver, then all you will see
+is a dummy MSDOS partition filling the whole disk.  You won't be able to mount
+any of the volumes on the disk.
+
+
+Booting
+-------
+
+If you enable LDM support, then lilo is capable of booting from any of the
+discovered partitions.  However, grub does not understand the LDM partitioning
+and cannot boot from a Dynamic Disk.
+
+
+More Documentation
+------------------
+
+There is an Overview of the LDM online together with complete Technical
+Documentation.  It can also be downloaded in html.
+
+  http://linux-ntfs.sourceforge.net/ldm/index.html
+  http://linux-ntfs.sourceforge.net/downloads.html
+
+If you have any LDM questions that aren't answered on the website, email me.
+
+Cheers,
+    FlatCap - Richard Russon
+    ldm@flatcap.org
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/00-INDEX linux-bk/Documentation/networking/00-INDEX
--- linux-2.4.19/Documentation/networking/00-INDEX	2001-02-09 00:32:44.000000000 +0000
+++ linux-bk/Documentation/networking/00-INDEX	2002-11-22 15:35:26.000000000 +0000
@@ -44,6 +44,10 @@
 	- the Digi International RightSwitch SE-X Ethernet driver
 dmfe.txt
 	- info on the Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver.
+e100.txt
+	- info on Intel's EtherExpress PRO/100 line of 10/100 boards
+e1000.txt
+	- info on Intel's E1000 line of gigabit ethernet boards
 eql.txt
 	- serial IP load balancing
 ethertap.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/8139too.txt linux-bk/Documentation/networking/8139too.txt
--- linux-2.4.19/Documentation/networking/8139too.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/networking/8139too.txt	2002-11-22 15:35:23.000000000 +0000
@@ -185,9 +185,22 @@
 Change History
 --------------
 
-Version 0.9.23 - January 16, 2002
+Version 0.9.26 - August 9, 2002
 
-* New, compile-time conditional for testing better RX reset
+* Fix MII ioctl phy id corruption.
+* Fix big-endian multicast bug.
+* Support register dumps via ethtool.
+* Fix several uses of 'len' after potential skb free, in dev->hard_start_xmit
+* Replace several "magic numbers" with their proper representation
+  constants in linux/mii.h.
+* Support ethtool media interface via generic kernel MII API
+* Export NIC-specific statistics via ethtool.
+* Proper support for RTL8139 rev K. (can be disabled via
+  compile-time conditional)
+* Add PCI ids for new 8139 boards.
+* Use ethernet crc via generic linux/crc32.h kernel API.
+* Better RX reset.  Old rx-reset method still available via
+  a compile-time conditional.
 * Only account specific RX errors if rx_status is !OK
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/NAPI_HOWTO.txt linux-bk/Documentation/networking/NAPI_HOWTO.txt
--- linux-2.4.19/Documentation/networking/NAPI_HOWTO.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/NAPI_HOWTO.txt	2002-11-22 15:35:22.000000000 +0000
@@ -0,0 +1,749 @@
+HISTORY:
+February 16/2002 -- revision 0.2.1:
+COR typo corrected
+February 10/2002 -- revision 0.2:
+some spell checking ;->
+January 12/2002 -- revision 0.1
+This is still work in progress so may change.
+To keep up to date please watch this space.
+
+Introduction to NAPI
+====================
+
+NAPI is a proven (www.cyberus.ca/~hadi/usenix-paper.tgz) technique
+to improve network performance on Linux. For more details please
+read that paper.
+NAPI provides a "inherent mitigation" which is bound by system capacity
+as can be seen from the following data collected by Robert on Gigabit 
+ethernet (e1000):
+
+ Psize    Ipps       Tput     Rxint     Txint    Done     Ndone
+ ---------------------------------------------------------------
+   60    890000     409362        17     27622        7     6823
+  128    758150     464364        21      9301       10     7738
+  256    445632     774646        42     15507       21    12906
+  512    232666     994445    241292     19147   241192     1062
+ 1024    119061    1000003    872519     19258   872511        0
+ 1440     85193    1000003    946576     19505   946569        0
+ 
+
+Legend:
+"Ipps" stands for input packets per second. 
+"Tput" == packets out of total 1M that made it out.
+"txint" == transmit completion interrupts seen
+"Done" == The number of times that the poll() managed to pull all
+packets out of the rx ring. Note from this that the lower the
+load the more we could clean up the rxring
+"Ndone" == is the converse of "Done". Note again, that the higher
+the load the more times we couldnt clean up the rxring.
+
+Observe that:
+when the NIC receives 890Kpackets/sec only 17 rx interrupts are generated. 
+The system cant handle the processing at 1 interrupt/packet at that load level. 
+At lower rates on the other hand, rx interrupts go up and therefore the
+interrupt/packet ratio goes up (as observable from that table). So there is
+possibility that under low enough input, you get one poll call for each
+input packet caused by a single interrupt each time. And if the system 
+cant handle interrupt per packet ratio of 1, then it will just have to 
+chug along ....
+
+
+0) Prerequisites:
+==================
+A driver MAY continue using the old 2.4 technique for interfacing
+to the network stack and not benefit from the NAPI changes.
+NAPI additions to the kernel do not break backward compatibility.
+NAPI, however, requires the following features to be available:
+
+A) DMA ring or enough RAM to store packets in software devices.
+
+B) Ability to turn off interrupts or maybe events that send packets up 
+the stack.
+
+NAPI processes packet events in what is known as dev->poll() method.
+Typically, only packet receive events are processed in dev->poll(). 
+The rest of the events MAY be processed by the regular interrupt handler 
+to reduce processing latency (justified also because there are not that 
+many of them).
+Note, however, NAPI does not enforce that dev->poll() only processes 
+receive events. 
+Tests with the tulip driver indicated slightly increased latency if
+all of the interrupt handler is moved to dev->poll(). Also MII handling
+gets a little trickier.
+The example used in this document is to move the receive processing only
+to dev->poll(); this is shown with the patch for the tulip driver.
+For an example of code that moves all the interrupt driver to 
+dev->poll() look at the ported e1000 code.
+
+There are caveats that might force you to go with moving everything to 
+dev->poll(). Different NICs work differently depending on their status/event 
+acknowledgement setup. 
+There are two types of event register ACK mechanisms.
+	I)  what is known as Clear-on-read (COR).
+	when you read the status/event register, it clears everything!
+	The natsemi and sunbmac NICs are known to do this.
+	In this case your only choice is to move all to dev->poll()
+
+	II) Clear-on-write (COW)
+	 i) you clear the status by writting a 1 in the bit-location you want.
+		These are the majority of the NICs and work the best with NAPI.
+		Put only receive events in dev->poll(); leave the rest in
+		the old interrupt handler.
+	 ii) whatever you write in the status register clears every thing ;->
+		Cant seem to find any supported by Linux which do this. If
+		someone knows such a chip email us please.
+		Move all to dev->poll()
+
+C) Ability to detect new work correctly.
+NAPI works by shutting down event interrupts when theres work and
+turning them on when theres none. 
+New packets might show up in the small window while interrupts were being 
+re-enabled (refer to appendix 2).  A packet might sneak in during the period 
+we are enabling interrupts. We only get to know about such a packet when the 
+next new packet arrives and generates an interrupt. 
+Essentially, there is a small window of opportunity for a race condition
+which for clarity we'll refer to as the "rotting packet".
+
+This is a very important topic and appendix 2 is dedicated for more 
+discussion.
+
+Locking rules and environmental guarantees
+==========================================
+
+-Guarantee: Only one CPU at any time can call dev->poll(); this is because
+only one CPU can pick the initial interrupt and hence the initial
+netif_rx_schedule(dev);
+- The core layer invokes devices to send packets in a round robin format.
+This implies receive is totaly lockless because of the guarantee only that 
+one CPU is executing it.
+-  contention can only be the result of some other CPU accessing the rx
+ring. This happens only in close() and suspend() (when these methods
+try to clean the rx ring); 
+****guarantee: driver authors need not worry about this; synchronization 
+is taken care for them by the top net layer.
+-local interrupts are enabled (if you dont move all to dev->poll()). For 
+example link/MII and txcomplete continue functioning just same old way. 
+This improves the latency of processing these events. It is also assumed that 
+the receive interrupt is the largest cause of noise. Note this might not 
+always be true. 
+[according to Manfred Spraul, the winbond insists on sending one 
+txmitcomplete interrupt for each packet (although this can be mitigated)].
+For these broken drivers, move all to dev->poll().
+
+For the rest of this text, we'll assume that dev->poll() only
+processes receive events.
+
+new methods introduce by NAPI
+=============================
+
+a) netif_rx_schedule(dev)
+Called by an IRQ handler to schedule a poll for device
+
+b) netif_rx_schedule_prep(dev)
+puts the device in a state which allows for it to be added to the
+CPU polling list if it is up and running. You can look at this as
+the first half of  netif_rx_schedule(dev) above; the second half
+being c) below.
+
+c) __netif_rx_schedule(dev)
+Add device to the poll list for this CPU; assuming that _prep above
+has already been called and returned 1.
+
+d) netif_rx_reschedule(dev, undo)
+Called to reschedule polling for device specifically for some
+deficient hardware. Read Appendix 2 for more details.
+
+e) netif_rx_complete(dev)
+
+Remove interface from the CPU poll list: it must be in the poll list
+on current cpu. This primitive is called by dev->poll(), when
+it completes its work. The device cannot be out of poll list at this
+call, if it is then clearly it is a BUG(). You'll know ;->
+
+All these above nethods are used below. So keep reading for clarity.
+
+Device driver changes to be made when porting NAPI
+==================================================
+
+Below we describe what kind of changes are required for NAPI to work.
+
+1) introduction of dev->poll() method 
+=====================================
+
+This is the method that is invoked by the network core when it requests
+for new packets from the driver. A driver is allowed to send upto
+dev->quota packets by the current CPU before yielding to the network
+subsystem (so other devices can also get opportunity to send to the stack).
+
+dev->poll() prototype looks as follows:
+int my_poll(struct net_device *dev, int *budget)
+
+budget is the remaining number of packets the network subsystem on the
+current CPU can send up the stack before yielding to other system tasks.
+*Each driver is responsible for decrementing budget by the total number of
+packets sent.
+	Total number of packets cannot exceed dev->quota.
+
+dev->poll() method is invoked by the top layer, the driver just sends if it 
+can to the stack the packet quantity requested.
+
+more on dev->poll() below after the interrupt changes are explained.
+
+2) registering dev->poll() method
+===================================
+
+dev->poll should be set in the dev->probe() method. 
+e.g:
+dev->open = my_open;
+.
+.
+/* two new additions */
+/* first register my poll method */
+dev->poll = my_poll;
+/* next register my weight/quanta; can be overriden in /proc */
+dev->weight = 16;
+.
+.
+dev->stop = my_close;
+
+
+
+3) scheduling dev->poll()
+=============================
+This involves modifying the interrupt handler and the code
+path which takes the packet off the NIC and sends them to the 
+stack.
+
+it's important at this point to introduce the classical D Becker 
+interrupt processor:
+
+------------------
+static void
+netdevice_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct my_private *tp = (struct my_private *)dev->priv;
+
+	int work_count = my_work_count;
+        status = read_interrupt_status_reg();
+        if (status == 0)
+                return;         /* Shared IRQ: not us */
+        if (status == 0xffff)
+                return;         /* Hot unplug */
+        if (status & error)
+		do_some_error_handling()
+        
+	do {
+		acknowledge_ints_ASAP();
+
+		if (status & link_interrupt) {
+			spin_lock(&tp->link_lock);
+			do_some_link_stat_stuff();
+			spin_unlock(&tp->link_lock);
+		}
+		
+		if (status & rx_interrupt) {
+			receive_packets(dev);
+		}
+
+		if (status & rx_nobufs) {
+			make_rx_buffs_avail();
+		}
+			
+		if (status & tx_related) {
+			spin_lock(&tp->lock);
+			tx_ring_free(dev);
+			if (tx_died)
+				restart_tx();
+			spin_unlock(&tp->lock);
+		}
+
+		status = read_interrupt_status_reg();
+
+	} while (!(status & error) || more_work_to_be_done);
+
+}
+
+----------------------------------------------------------------------
+
+We now change this to what is shown below to NAPI-enable it:
+
+----------------------------------------------------------------------
+static void
+netdevice_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *)dev_instance;
+	struct my_private *tp = (struct my_private *)dev->priv;
+
+        status = read_interrupt_status_reg();
+        if (status == 0)
+                return;         /* Shared IRQ: not us */
+        if (status == 0xffff)
+                return;         /* Hot unplug */
+        if (status & error)
+		do_some_error_handling();
+        
+	do {
+/************************ start note *********************************/		
+		acknowledge_ints_ASAP();  // dont ack rx and rxnobuff here
+/************************ end note *********************************/		
+
+		if (status & link_interrupt) {
+			spin_lock(&tp->link_lock);
+			do_some_link_stat_stuff();
+			spin_unlock(&tp->link_lock);
+		}
+/************************ start note *********************************/		
+		if (status & rx_interrupt || (status & rx_nobuffs)) {
+			if (netif_rx_schedule_prep(dev)) {
+
+				/* disable interrupts caused 
+			         *	by arriving packets */
+				disable_rx_and_rxnobuff_ints();
+				/* tell system we have work to be done. */
+				__netif_rx_schedule(dev);
+			} else {
+				printk("driver bug! interrupt while in poll\n");
+				/* FIX by disabling interrupts  */
+				disable_rx_and_rxnobuff_ints();
+			}
+		}
+/************************ end note note *********************************/		
+			
+		if (status & tx_related) {
+			spin_lock(&tp->lock);
+			tx_ring_free(dev);
+
+			if (tx_died)
+				restart_tx();
+			spin_unlock(&tp->lock);
+		}
+
+		status = read_interrupt_status_reg();
+
+/************************ start note *********************************/		
+	} while (!(status & error) || more_work_to_be_done(status));
+/************************ end note note *********************************/		
+
+}
+
+---------------------------------------------------------------------
+
+
+We note several things from above:
+
+I) Any interrupt source which is caused by arriving packets is now
+turned off when it occurs. Depending on the hardware, there could be
+several reasons that arriving packets would cause interrupts; these are the
+interrupt sources we wish to avoid. The two common ones are a) a packet 
+arriving (rxint) b) a packet arriving and finding no DMA buffers available
+(rxnobuff) .
+This means also acknowledge_ints_ASAP() will not clear the status
+register for those two items above; clearing is done in the place where 
+proper work is done within NAPI; at the poll() and refill_rx_ring() 
+discussed further below.
+netif_rx_schedule_prep() returns 1 if device is in running state and
+gets successfully added to the core poll list. If we get a zero value
+we can _almost_ assume are already added to the list (instead of not running. 
+Logic based on the fact that you shouldnt get interrupt if not running)
+We rectify this by disabling rx and rxnobuf interrupts.
+
+II) that receive_packets(dev) and make_rx_buffs_avail() may have dissapeared.
+These functionalities are still around actually......
+
+infact, receive_packets(dev) is very close to my_poll() and 
+make_rx_buffs_avail() is invoked from my_poll()
+
+4) converting receive_packets() to dev->poll()
+===============================================
+
+We need to convert the classical D Becker receive_packets(dev) to my_poll()
+
+First the typical receive_packets() below:
+-------------------------------------------------------------------
+
+/* this is called by interrupt handler */
+static void receive_packets (struct net_device *dev)
+{
+
+	struct my_private *tp = (struct my_private *)dev->priv;
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+	int entry = cur_rx % RX_RING_SIZE;
+	int received = 0;
+	int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
+
+	while (rx_ring_not_empty) {
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+                /* read size+status of next frame from DMA ring buffer */
+		/* the number 16 and 4 are just examples */
+                rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+                rx_size = rx_status >> 16;
+                pkt_size = rx_size - 4;
+
+		/* process errors */
+                if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                    (!(rx_status & RxStatusOK))) {
+                        netdrv_rx_err (rx_status, dev, tp, ioaddr);
+                        return;
+                }
+
+                if (--rx_work_limit < 0)
+                        break;
+
+		/* grab a skb */
+                skb = dev_alloc_skb (pkt_size + 2);
+                if (skb) {
+			.
+			.
+			netif_rx (skb);
+			.
+			.
+                } else {  /* OOM */
+			/*seems very driver specific ... some just pass
+			whatever is on the ring already. */
+                }
+
+		/* move to the next skb on the ring */
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+		received++ ;
+
+        }
+
+	/* store current ring pointer state */
+        tp->cur_rx = cur_rx;
+
+        /* Refill the Rx ring buffers if they are needed */
+	refill_rx_ring();
+	.
+	.
+
+}
+-------------------------------------------------------------------
+We change it to a new one below; note the additional parameter in
+the call.
+
+-------------------------------------------------------------------
+
+/* this is called by the network core */
+static void my_poll (struct net_device *dev, int *budget)
+{
+
+	struct my_private *tp = (struct my_private *)dev->priv;
+	rx_ring = tp->rx_ring;
+	cur_rx = tp->cur_rx;
+	int entry = cur_rx % RX_BUF_LEN;
+	/* maximum packets to send to the stack */
+/************************ note note *********************************/		
+	int rx_work_limit = dev->quota;
+
+/************************ end note note *********************************/		
+    do {  // outer beggining loop starts here
+
+	clear_rx_status_register_bit();
+
+	while (rx_ring_not_empty) {
+		u32 rx_status;
+		unsigned int rx_size;
+		unsigned int pkt_size;
+		struct sk_buff *skb;
+                /* read size+status of next frame from DMA ring buffer */
+		/* the number 16 and 4 are just examples */
+                rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
+                rx_size = rx_status >> 16;
+                pkt_size = rx_size - 4;
+
+		/* process errors */
+                if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+                    (!(rx_status & RxStatusOK))) {
+                        netdrv_rx_err (rx_status, dev, tp, ioaddr);
+                        return;
+                }
+
+/************************ note note *********************************/		
+                if (--rx_work_limit < 0) { /* we got packets, but no quota */
+			/* store current ring pointer state */
+			tp->cur_rx = cur_rx;
+
+			/* Refill the Rx ring buffers if they are needed */
+			refill_rx_ring(dev);
+                        goto not_done;
+		}
+/**********************  end note **********************************/
+
+		/* grab a skb */
+                skb = dev_alloc_skb (pkt_size + 2);
+                if (skb) {
+			.
+			.
+/************************ note note *********************************/		
+			netif_receive_skb (skb);
+/**********************  end note **********************************/
+			.
+			.
+                } else {  /* OOM */
+			/*seems very driver specific ... common is just pass
+			whatever is on the ring already. */
+                }
+
+		/* move to the next skb on the ring */
+		entry = (++tp->cur_rx) % RX_RING_SIZE;
+		received++ ;
+
+        }
+
+	/* store current ring pointer state */
+        tp->cur_rx = cur_rx;
+
+        /* Refill the Rx ring buffers if they are needed */
+	refill_rx_ring(dev);
+	
+	/* no packets on ring; but new ones can arrive since we last 
+	   checked  */
+	status = read_interrupt_status_reg();
+	if (rx status is not set) {
+                        /* If something arrives in this narrow window,
+			an interrupt will be generated */
+                        goto done;
+	}
+	/* done! at least thats what it looks like ;->
+	if new packets came in after our last check on status bits
+	they'll be caught by the while check and we go back and clear them 
+	since we havent exceeded our quota */
+    } while (rx_status_is_set); 
+
+done:
+
+/************************ note note *********************************/		
+        dev->quota -= received;
+        *budget -= received;
+
+        /* If RX ring is not full we are out of memory. */
+        if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                goto oom;
+
+	/* we are happy/done, no more packets on ring; put us back
+	to where we can start processing interrupts again */
+        netif_rx_complete(dev);
+	enable_rx_and_rxnobuf_ints();
+
+       /* The last op happens after poll completion. Which means the following:
+        * 1. it can race with disabling irqs in irq handler (which are done to 
+	* schedule polls)
+        * 2. it can race with dis/enabling irqs in other poll threads
+        * 3. if an irq raised after the begining of the outer  beginning 
+        * loop(marked in the code above), it will be immediately
+        * triggered here.
+        *
+        * Summarizing: the logic may results in some redundant irqs both
+        * due to races in masking and due to too late acking of already
+        * processed irqs. The good news: no events are ever lost.
+        */
+
+        return 0;   /* done */
+
+not_done:
+        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+            tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                refill_rx_ring(dev);
+
+        if (!received) {
+                printk("received==0\n");
+                received = 1;
+        }
+        dev->quota -= received;
+        *budget -= received;
+        return 1;  /* not_done */
+
+oom:
+        /* Start timer, stop polling, but do not enable rx interrupts. */
+	start_poll_timer(dev);
+        return 0;  /* we'll take it from here so tell core "done"*/
+
+/************************ End note note *********************************/		
+}
+-------------------------------------------------------------------
+
+From above we note that:
+0) rx_work_limit = dev->quota 
+1) refill_rx_ring() is in charge of clearing the bit for rxnobuff when
+it does the work.
+2) We have a done and not_done state.
+3) instead of netif_rx() we call netif_receive_skb() to pass the skb.
+4) we have a new way of handling oom condition
+5) A new outer for (;;) loop has been added. This serves the purpose of
+ensuring that if a new packet has come in, after we are all set and done,
+and we have not exceeded our quota that we continue sending packets up.
+ 
+
+-----------------------------------------------------------
+Poll timer code will need to do the following:
+
+a) 
+
+        if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
+            tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) 
+                refill_rx_ring(dev);
+
+        /* If RX ring is not full we are still out of memory.
+	   Restart the timer again. Else we re-add ourselves 
+           to the master poll list.
+         */
+
+        if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
+                restart_timer();
+
+	else netif_rx_schedule(dev);  /* we are back on the poll list */
+	
+5) dev->close() and dev->suspend() issues
+==========================================
+The driver writter neednt worry about this. The top net layer takes
+care of it.
+
+6) Adding new Stats to /proc 
+=============================
+In order to debug some of the new features, we introduce new stats
+that need to be collected.
+TODO: Fill this later.
+
+APPENDIX 1: discussion on using ethernet HW FC
+==============================================
+Most chips with FC only send a pause packet when they run out of Rx buffers.
+Since packets are pulled off the DMA ring by a softirq in NAPI,
+if the system is slow in grabbing them and we have a high input
+rate (faster than the system's capacity to remove packets), then theoretically
+there will only be one rx interrupt for all packets during a given packetstorm.
+Under low load, we might have a single interrupt per packet.
+FC should be programmed to apply in the case when the system cant pull out
+packets fast enough i.e send a pause only when you run out of rx buffers.
+Note FC in itself is a good solution but we have found it to not be
+much of a commodity feature (both in NICs and switches) and hence falls
+under the same category as using NIC based mitigation. Also experiments
+indicate that its much harder to resolve the resource allocation
+issue (aka lazy receiving that NAPI offers) and hence quantify its usefullness
+proved harder. In any case, FC works even better with NAPI but is not
+necessary.
+
+
+APPENDIX 2: the "rotting packet" race-window avoidance scheme 
+=============================================================
+
+There are two types of associations seen here
+
+1) status/int which honors level triggered IRQ
+
+If a status bit for receive or rxnobuff is set and the corresponding 
+interrupt-enable bit is not on, then no interrupts will be generated. However, 
+as soon as the "interrupt-enable" bit is unmasked, an immediate interrupt is 
+generated.  [assuming the status bit was not turned off].
+Generally the concept of level triggered IRQs in association with a status and
+interrupt-enable CSR register set is used to avoid the race.
+
+If we take the example of the tulip:
+"pending work" is indicated by the status bit(CSR5 in tulip).
+the corresponding interrupt bit (CSR7 in tulip) might be turned off (but
+the CSR5 will continue to be turned on with new packet arrivals even if
+we clear it the first time)
+Very important is the fact that if we turn on the interrupt bit on when
+status is set that an immediate irq is triggered.
+ 
+If we cleared the rx ring and proclaimed there was "no more work
+to be done" and then went on to do a few other things;  then when we enable
+interrupts, there is a possibility that a new packet might sneak in during
+this phase. It helps to look at the pseudo code for the tulip poll
+routine:
+
+--------------------------
+        do {
+                ACK;
+                while (ring_is_not_empty()) {
+                        work-work-work
+                        if quota is exceeded: exit, no touching irq status/mask
+                }
+                /* No packets, but new can arrive while we are doing this*/
+                CSR5 := read
+                if (CSR5 is not set) {
+                        /* If something arrives in this narrow window here,
+                        *  where the comments are ;-> irq will be generated */
+                        unmask irqs;
+                        exit poll;
+                }
+        } while (rx_status_is_set);
+------------------------
+
+CSR5 bit of interest is only the rx status. 
+If you look at the last if statement: 
+you just finished grabbing all the packets from the rx ring .. you check if
+status bit says theres more packets just in ... it says none; you then
+enable rx interrupts again; if a new packet just came in during this check,
+we are counting that CSR5 will be set in that small window of opportunity
+and that by re-enabling interrupts, we would actually triger an interrupt
+to register the new packet for processing.
+
+[The above description nay be very verbose, if you have better wording 
+that will make this more understandable, please suggest it.]
+
+2) non-capable hardware
+
+These do not generally respect level triggered IRQs. Normally,
+irqs may be lost while being masked and the only way to leave poll is to do
+a double check for new input after netif_rx_complete() is invoked
+and re-enable polling (after seeing this new input).
+
+Sample code:
+
+---------
+	.
+	.
+restart_poll:
+	while (ring_is_not_empty()) {
+		work-work-work
+		if quota is exceeded: exit, not touching irq status/mask
+	}
+	.
+	.
+	.
+	enable_rx_interrupts()
+	netif_rx_complete(dev);
+	if (ring_has_new_packet() && netif_rx_reschedule(dev, received)) {
+		disable_rx_and_rxnobufs()
+		goto restart_poll
+	} while (rx_status_is_set);
+---------
+		
+Basically netif_rx_complete() removes us from the poll list, but because a
+new packet which will never be caught due to the possibility of a race
+might come in, we attempt to re-add ourselves to the poll list. 
+
+
+
+--------------------------------------------------------------------
+
+relevant sites:
+==================
+ftp://robur.slu.se/pub/Linux/net-development/NAPI/
+
+
+--------------------------------------------------------------------
+TODO: Write net-skeleton.c driver.
+-------------------------------------------------------------
+
+Authors:
+========
+Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Jamal Hadi Salim <hadi@cyberus.ca>
+Robert Olsson <Robert.Olsson@data.slu.se>
+
+Acknowledgements:
+================
+People who made this document better:
+
+Lennert Buytenhek <buytenh@gnu.org>
+Andrew Morton  <akpm@zip.com.au>
+Manfred Spraul <manfred@colorfullife.com>
+Donald Becker <becker@scyld.com>
+Jeff Garzik 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/dl2k.txt linux-bk/Documentation/networking/dl2k.txt
--- linux-2.4.19/Documentation/networking/dl2k.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/networking/dl2k.txt	2002-11-22 15:35:24.000000000 +0000
@@ -1,7 +1,7 @@
 
     D-Link DL2000-based Gigabit Ethernet Adapter Installation
     for Linux
-    Jan 29, 2002
+    May 23, 2002
 
 Contents
 ========
@@ -202,7 +202,7 @@
 				  1000mbps_fd and 1000mbps_hd types are only
 				  available for fiber adapter.
 
-vlan=[0|1]			- Specifies the VLAN ID. If vlan=0, the
+vlan=n				- Specifies the VLAN ID. If vlan=0, the
 				  Virtual Local Area Network (VLAN) function is
 				  disable.
 
@@ -211,24 +211,34 @@
 				  function is disabled.
 				  Jumbo frame usually improve the performance
 				  int gigabit.
+				  This feature need jumbo frame compatible 
+				  remote.
 				  
-rx_coalesce=n			- Rx frame count each interrupt.
-rx_timeout=n			- Rx DMA wait time for an interrupt. Proper 
-				  values of rx_coalesce and rx_timeout bring 
-				  a conspicuous performance in the fast machine.
-				  Ex. rx_coalesce=5 and rx_timeout=750 
-
-tx_coalesce=n			- Tx transmit count each TxComp interrupt.
-				  Setting value larger than 1 will improve 
-				  performance, but this is possible to lower 
-				  stability in slow UP machines. By default, 
-				  tx_coalesce=1. (dl2k)
+rx_coalesce=m			- Number of rx frame handled each interrupt.
+rx_timeout=n			- Rx DMA wait time for an interrupt. 
+				  If set rx_coalesce > 0, hardware only assert 
+				  an interrupt for m frames. Hardware won't 
+				  assert rx interrupt until m frames received or
+				  reach timeout of n * 640 nano seconds. 
+				  Set proper rx_coalesce and rx_timeout can 
+				  reduce congestion collapse and overload which
+				  has been a bottlenect for high speed network.
 				  
-tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=1, 
-				  the Tx flow control enable.
+				  For example, rx_coalesce=10 rx_timeout=800.
+				  that is, hardware assert only 1 interrupt 
+				  for 10 frames received or timeout of 512 us. 
+
+tx_coalesce=n			- Number of tx frame handled each interrupt.
+				  Set n > 1 can reduce the interrupts 
+				  congestion usually lower performance of
+				  high speed network card. Default is 16.
 				  
-rx_flow=[1|0]			- Specifies the Rx flow control. If rx_flow=1, 
-				  the Rx flow control enable.
+tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=0, 
+				  the Tx flow control disable else driver
+				  autodetect.
+rx_flow=[1|0]			- Specifies the Rx flow control. If rx_flow=0, 
+				  the Rx flow control enable else driver
+				  autodetect.
 
 
 Configuration Script Sample
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/e100.txt linux-bk/Documentation/networking/e100.txt
--- linux-2.4.19/Documentation/networking/e100.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/e100.txt	2002-11-22 15:35:27.000000000 +0000
@@ -0,0 +1,253 @@
+Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
+==============================================================
+
+September 16, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- CPU Cycle Saver
+- Additional Configurations
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of
+Adapters, version 2.1.x.  This driver includes support for Itanium(TM)-based 
+systems.
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers 
+in this release:
+
+Controller  Adapter Name                            Board IDs
+----------  ------------                            ---------
+
+82558       PRO/100+ PCI Adapter                    668081-xxx, 689661-xxx
+
+82558       PRO/100+ Management Adapter             691334-xxx, 701738-xxx,
+                                                    721383-xxx
+
+82558       PRO/100+ Dual Port Server Adapter       714303-xxx, 711269-xxx, 
+                                                    A28276-xxx
+
+82558       PRO/100+ PCI Server Adapter             710550-xxx
+
+82550       PRO/100 S Server Adapter                752438-xxx (82550)
+82559                                               A56831-xxx, A10563-xxx,
+                                                    A12171-xxx, A12321-xxx, 
+                                                    A12320-xxx, A12170-xxx
+                                                    748568-xxx (82559)
+                                                    748565-xxx (82559)
+
+
+82550       PRO/100 S Desktop Adapter               751767-xxx (82550)
+82559                                               748592-xxx, A12167-xxx, 
+                                                    A12318-xxx, A12317-xxx, 
+                                                    A12165-xxx
+                                                    748569-xxx (82559)
+
+
+
+82559       PRO/100+ Server Adapter                 729757-xxx
+
+82559       PRO/100 S Management Adapter            748566-xxx, 748564-xxx
+
+82550       PRO/100 S Dual Port Server Adapter      A56831-xxx
+
+82551       PRO/100 M Desktop Adapter               A80897-xxx
+
+            PRO/100 S Advanced Management Adapter   747842-xxx, 745171-xxx
+
+CNR         PRO/100 VE Desktop Adapter              A10386-xxx, A10725-xxx, 
+                                                    A23801-xxx, A19716-xxx
+
+
+            PRO/100 VM Desktop Adapter              A14323-xxx, A19725-xxx, 
+                                                    A23801-xxx, A22220-xxx, 
+                                                    A23796-xxx
+   
+
+To verify that your adapter is supported, find the board ID number on the 
+adapter. Look for a label that has a barcode and a number in the format 
+A12345-001. Match this to the list of numbers above.
+
+For more information on how to identify your adapter, go to the Adapter & 
+Driver ID Guide at:
+
+  http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel PRO/100 network driver for Linux, see:
+
+  http://downloadfinder.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+The following optional parameters are used by entering them on the command 
+line with the modprobe or insmod command using this syntax:
+
+     modprobe e100 [<option>=<VAL1>,<VAL2>,...]
+
+     insmod e100 [<option>=<VAL1>,<VAL2>,...] 
+
+For example, with two Intel PRO/100 PCI adapters, entering:
+	
+     modprobe e100 TxDescriptors=32,128
+
+loads the e100 driver with 32 TX resources for the first adapter and 128 TX 
+resources for the second adapter. This configuration favors the second 
+adapter. The driver supports up to 16 network adapters concurrently.
+
+The default value for each parameter is generally the recommended setting,
+unless otherwise noted.
+
+NOTE: Giving any command line option the value "-1" causes the driver to use 
+      the appropriate default value for that option, as if no value was 
+      specified.
+
+
+BundleMax
+Valid Range: 1-65535
+Default Value: 6
+   This parameter holds the maximum number of small packets (less than 128
+   bytes) in a bundle. Suggested values range from 2 to 10. See "CPU Cycle 
+   Saver."
+
+BundleSmallFr
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0
+   The value 1 (on) causes small packets (less than 128 bytes) to be bundled. 
+   See "CPU Cycle Saver."
+
+e100_speed_duplex
+Valid Range: 0-4 (1=10half;2=10full;3=100half;4=100full)
+Default Value: 0
+   The default value of 0 sets the adapter to auto-negotiate. Other values
+   set the adapter to forced speed and duplex. 
+   Example usage: insmod e100.o e100_speed_duplex=4,4 (for two adapters)
+
+flow_control
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0
+   This parameter controls the automatic generation(Tx) and response(Rx) to 
+   Ethernet PAUSE frames. flow_control should NOT be set to 1 when the 
+   adapter is connected to an interface that does not support Ethernet PAUSE 
+   frames and when the e100_speed_duplex parameter is NOT set to zero. 
+
+IntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 1536
+   This parameter holds the number of time units (in adapter terminology)
+   until the adapter generates an interrupt. The recommended value for 
+   IntDelay is 1536 (upon initialization). Suggested values range from 
+   512 to 2048. See "CPU Cycle Saver."
+
+IFS
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+  Inter Frame Spacing (IFS) aims to reduce the number of Ethernet frame
+  collisions by altering the time between frame transmissions. When IFS is 
+  enabled the driver tries to find an optimal IFS value. It is used only at 
+  half duplex.
+
+RxDescriptors
+Valid Range: 8-1024
+Default Value: 64
+   This parameter defines the number of receive descriptors allocated by 
+   the driver. Increasing this value allows the driver to buffer more 
+   incoming packets before the driver is required to service an interrupt. 
+   The maximum value for Itanium-based systems is 64.
+
+TxDescriptors
+Valid Range: 19-1024
+Default Value: 64
+   This value is the number of transmit descriptors allocated by the driver. 
+   Increasing this value allows the protocol stack to queue more transmits at
+   the driver level. The maximum value for Itanium-based systems is 64.
+
+ucode
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 0 for 82558-based adapters
+               1 for 82559, 82550, and 82551-based adapters
+   On uploads the micro code to the adapter, which enables CPU Cycle Saver. 
+   See the section "CPU Cycle Saver" below.
+   Example usage: insmod e100.o ucode=1
+
+   Not available on 82557-based adapters.
+
+XsumRX
+Valid Range: 0-1 (0=off, 1=on)
+Default Value: 1
+   On allows Rx checksum offloading for TCP/UDP packets. Requires that the 
+   hardware support this feature.
+
+   Not available on 82557 and 82558-based adapters.
+
+
+CPU Cycle Saver
+================
+
+CPU Cycle Saver reduces CPU utilization by reducing the number of interrupts 
+that the adapter generates.
+
+When CPU Cycle Saver is turned off, the adapter generates one interrupt for 
+every frame that is received. This means that the operating system stops what
+it is doing and switches to the network driver in order to process the 
+receive.
+
+When CPU Cycle Saver is on, the adapter does not generate an interrupt for 
+every frame it receives. Instead, it waits until it receives several frames 
+before generating an interrupt. This reduces the amount of time spent 
+switching to and from the driver. 
+
+CPU Cycle Saver consists of these arguments: IntDelay, BundleMax and 
+BundleSmallFr. When IntDelay is increased, the adapter waits longer for 
+frames to arrive before generating the interrupt. By increasing BundleMax, 
+the network adapter waits for the number of small frames (less than 128 bytes)
+specified to arrive before generating the interrupt. When BundleSmallFr is 
+disabled, the adapter does not bundle small packets. Such small packets are 
+often, but not always, control packets that are better served immediately;
+therefore, BundleSmallFr is disabled by default.
+
+For most users, it is recommended that CPU Cycle Saver be used with the 
+default values specified in the Command Line Parameters section. However, in 
+some cases, performance problems may occur with CPU Cycle Saver. If such 
+problems are observed, we recommend turning off this feature by setting 
+ucode=0.
+
+
+Support
+=======
+
+For general information, go to the Intel support website at:
+
+    http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to 
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement 
+between you ('Licensee') and Intel. Do not use or load this software or any 
+associated materials (collectively, the 'Software') until you have carefully 
+read the full terms and conditions of the LICENSE located in this software 
+package. By loading or using the Software, you agree to the terms of this 
+Agreement. If you do not agree with the terms of this Agreement, do not 
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/e1000.txt linux-bk/Documentation/networking/e1000.txt
--- linux-2.4.19/Documentation/networking/e1000.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/e1000.txt	2002-11-22 15:35:31.000000000 +0000
@@ -0,0 +1,302 @@
+Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
+===============================================================
+
+October 12, 2002
+
+
+Contents
+========
+
+- In This Release
+- Supported Adapters
+- Command Line Parameters
+- Speed and Duplex Configuration
+- Additional Configurations
+- Known Issues
+- Support
+
+
+In This Release
+===============
+
+This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
+of Adapters, version 4.4.x.  This driver includes support for 
+Itanium(TM)-based systems.
+
+This release version includes the following:
+
+   - Support for the ethtool 1.6 interface. A third-party application can use
+     the ethtool interface to get and set driver parameters.
+
+   - Zero copy. This feature provides faster data throughput. Enabled by
+     default in supporting kernels. It is not supported on the Intel(R)
+     PRO/1000 Gigabit Server Adapter.
+
+Features include:
+
+   - Support for the 82545 and 82546-based adapters listed below
+
+   - Wake on LAN* support via ethtool for 82540, 82544, 82545, and 82546-
+     based adapters
+
+   - Adaptive IFS for increased performance at half duplex
+
+
+
+Supported Adapters
+==================
+
+The following Intel network adapters are compatible with the drivers in this
+release:
+
+   Controller  Adapter Name                         Board IDs
+   ----------  ------------                         ---------
+
+   82542       PRO/1000 Gigabit Server Adapter      700262-xxx, 717037-xxx
+
+   82543       PRO/1000 F Server Adapter            738640-xxx, A38888-xxx
+
+   82543       PRO/1000 T Server Adapter            A19845-xxx, A33948-xxx
+
+   82544       PRO/1000 XT Server Adapter           A51580-xxx
+
+   82544       PRO/1000 XF Server Adapter           A50484-xxx
+
+   82544       PRO/1000 T Desktop Adapter           A62947-xxx
+
+   82540       PRO/1000 MT Desktop Adapter          A78408-xxx
+
+   82545       PRO/1000 MT Server Adapter           A92165-xxx
+
+   82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
+
+   82545       PRO/1000 MF Server Adapter           A91622-xxx
+
+   82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
+
+   82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx
+
+
+To verify your Intel adapter is supported, find the board ID number on the
+adapter. Look for a label that has a barcode and a number in the format of
+123456-001 (six digits hyphen three digits). Match this to the list of
+numbers above.
+
+For more information on how to identify your adapter, go to the Adapter &
+Driver ID Guide at:
+
+    http://support.intel.com/support/network/adapter/pro100/21397.htm
+
+For the latest Intel network drivers for Linux, go to:
+
+    http://appsr.intel.com/scripts-df/support_intel.asp
+
+
+Command Line Parameters
+=======================
+
+If the driver is built as a module, the following optional parameters are 
+used by entering them on the command line with the modprobe or insmod command. 
+For example, with two PRO/1000 PCI adapters, entering:
+
+    insmod e1000 TxDescriptors=80,128
+
+loads the e1000 driver with 80 TX resources for the first adapter and 128 TX
+resources for the second adapter.
+
+For more information about the AutoNeg, Duplex, and Speed parameters, see the
+"Speed and Duplex Configuration" section in this document.
+
+
+AutoNeg (adapters using copper connections only)
+Valid Range: 0x01-0x0F, 0x20-0x2F
+Default Value: 0x2F
+    This parameter is a bit mask that specifies which speed and duplex
+    settings the board advertises. When this parameter is used, the Speed and
+    Duplex parameters must not be specified.  
+
+Duplex (adapters using copper connections only)
+Valid Range: 0-2 (0=auto-negotiate, 1=half, 2=full)
+Default Value: 0
+    Defines the direction in which data is allowed to flow. Can by either one 
+    or two-directional. If both Duplex and the link partner are set to auto-
+    negotiate, the board auto-detects the correct duplex. If the link partner
+    is forced (either full or half), Duplex defaults to half-duplex.
+
+FlowControl
+Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
+Default: Read flow control settings from the EEPROM
+    This parameter controls the automatic generation(Tx) and response(Rx) to 
+    Ethernet PAUSE frames.
+
+RxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+Default Value: 80
+    This value is the number of receive descriptors allocated by the driver. 
+    Increasing this value allows the driver to buffer more incoming packets. 
+    Each descriptor is 16 bytes.  A receive buffer is also allocated for each
+    descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending 
+    on the MTU setting. The maximum MTU size is 16110.
+
+    NOTE: MTU designates the frame size. It only needs to be set for Jumbo 
+          Frames.
+
+RxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 0
+    This value delays the generation of receive interrupts in units of 1.024 
+    microseconds.  Receive interrupt reduction can improve CPU efficiency if 
+    properly tuned for specific network traffic. Increasing this value adds 
+    extra latency to frame reception and can end up decreasing the throughput 
+    of TCP traffic. If the system is reporting dropped receives, this value 
+    may be set too high, causing the driver to run out of available receive 
+    descriptors.
+
+    CAUTION: When setting RxIntDelay to a value other than 0, adapters may 
+             hang (stop transmitting) under certain network conditions. If
+             this occurs a NETDEV WATCHDOG message is logged in the system
+             event log. In addition, the controller is automatically reset,
+             restoring the network connection. To eliminate the potential for
+             the hang ensure that RxIntDelay is set to 0.
+
+RxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+Valid Range: 0-65535 (0=off)
+Default Value: 128
+    This value, in units of 1.024 microseconds, limits the delay in which a 
+    transmit interrupt is generated. Useful only if RxIntDelay is non-zero, 
+    this value ensures that an interrupt is generated after the initial 
+    packet is received within the set amount of time.  Proper tuning,
+    along with RxIntDelay, may improve traffic throughput in specific network
+    conditions.
+
+Speed (adapters using copper connections only)
+Valid Settings: 0, 10, 100, 1000
+Default Value: 0 (auto-negotiate at all supported speeds)
+    Speed forces the line speed to the specified value in megabits per second
+    (Mbps). If this parameter is not specified or is set to 0 and the link 
+    partner is set to auto-negotiate, the board will auto-detect the correct 
+    speed. Duplex must also be set when Speed is set to either 10 or 100.
+
+TxDescriptors
+Valid Range: 80-256 for 82542 and 82543-based adapters
+             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+Default Value: 256
+    This value is the number of transmit descriptors allocated by the driver.
+    Increasing this value allows the driver to queue more transmits. Each 
+    descriptor is 16 bytes.
+
+TxIntDelay
+Valid Range: 0-65535 (0=off)
+Default Value: 64
+    This value delays the generation of transmit interrupts in units of 
+    1.024 microseconds.  Transmit interrupt reduction can improve CPU
+    efficiency if properly tuned for specific network traffic. If the
+    system is reporting dropped transmits, this value may be set too high
+    causing the driver to run out of available transmit descriptors.
+
+TxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+Valid Range: 0-65535 (0=off)
+Default Value: 64
+    This value, in units of 1.024 microseconds, limits the delay in which a 
+    transmit interrupt is generated. Useful only if TxIntDelay is non-zero, 
+    this value ensures that an interrupt is generated after the initial 
+    packet is sent on the wire within the set amount of time.  Proper tuning,
+    along with TxIntDelay, may improve traffic throughput in specific 
+    network conditions.
+
+XsumRX (not available on the PRO/1000 Gigabit Server Adapter)
+Valid Range: 0-1
+Default Value: 1
+    A value of '1' indicates that the driver should enable IP checksum
+    offload for received packets (both UDP and TCP) to the adapter hardware.
+
+
+Speed and Duplex Configuration
+==============================
+
+Three keywords are used to control the speed and duplex configuration. These
+keywords are Speed, Duplex, and AutoNeg.
+
+If the board uses a fiber interface, these keywords are ignored, and the
+fiber interface board only links at 1000 Mbps full-duplex.
+
+For copper-based boards, the keywords interact as follows:
+
+  The default operation is auto-negotiate. The board advertises all supported
+  speed and duplex combinations, and it links at the highest common speed and
+  duplex mode IF the link partner is set to auto-negotiate.
+
+  If Speed = 1000, limited auto-negotiation is enabled and only 1000 Mbps is
+  advertised (The 1000BaseT spec requires auto-negotiation.)
+
+  If Speed = 10 or 100, then both Speed and Duplex must be set. Auto-
+  negotiation is disabled, and the AutoNeg parameter is ignored. Partner MUST
+  also be forced.
+
+The AutoNeg parameter is used when more control is required over the auto-
+negotiation process.  When this parameter is used, Speed and Duplex must not
+be specified.  This parameter is a bitmap that specifies which speed and
+duplex settings are advertised to the link partner.
+
+Bit            7      6      5       4       3      2      1       0
+Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
+Duplex                       Full            Full   Half   Full    Half
+
+Note that setting AutoNeg does not guarantee that the board will link at the
+highest specified speed or duplex mode, but the board will link at the
+highest possible speed/duplex of the link partner IF the link partner is also
+set to auto-negotiate. If the link partner is forced speed/duplex, the
+adapter MUST be forced to the same speed/duplex.
+
+
+Additional Configurations
+=========================
+
+  Jumbo Frames
+  ------------
+
+  The driver supports Jumbo Frames for all adapters except 82542-based
+  adapters.  Jumbo Frames support is enabled by changing the MTU to a value
+  larger than the default of 1500.  Use the ifconfig command to increase the
+  MTU size. For example:
+
+        ifconfig ethx mtu 9000 up
+
+
+Known Issues
+============
+
+  Jumbo Frames System Requirement
+  -------------------------------
+
+  Memory allocation failures have been observed on Linux systems with 64 MB
+  of RAM or less that are running Jumbo Frames. If you are using Jumbo
+  Frames, your system may require more than the advertised minimum
+  requirement of 64 MB of system memory.
+
+
+Support
+=======
+
+For general information and support, go to the Intel support website at:
+
+    http://support.intel.com
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related to
+the issue to linux.nics@intel.com.
+
+
+License
+=======
+
+This software program is released under the terms of a license agreement
+between you ('Licensee') and Intel. Do not use or load this software or any
+associated materials (collectively, the 'Software') until you have carefully
+read the full terms and conditions of the LICENSE located in this software
+package. By loading or using the Software, you agree to the terms of this
+Agreement. If you do not agree with the terms of this Agreement, do not
+install or use the Software.
+
+* Other names and brands may be claimed as the property of others.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/ewrk3.txt linux-bk/Documentation/networking/ewrk3.txt
--- linux-2.4.19/Documentation/networking/ewrk3.txt	1998-05-21 01:54:34.000000000 +0000
+++ linux-bk/Documentation/networking/ewrk3.txt	2002-11-22 15:35:25.000000000 +0000
@@ -24,6 +24,7 @@
     kernel with the ewrk3 configuration turned off and reboot.
     5) insmod ewrk3.o
           [Alan Cox: Changed this so you can insmod ewrk3.o irq=x io=y]
+          [Adam Kropelin: Multiple cards now supported by irq=x1,x2 io=y1,y2]
     6) run the net startup bits for your new eth?? interface manually 
     (usually /etc/rc.inet[12] at boot time). 
     7) enjoy!
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/khttpd.txt linux-bk/Documentation/networking/khttpd.txt
--- linux-2.4.19/Documentation/networking/khttpd.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/networking/khttpd.txt	2002-11-22 15:35:24.000000000 +0000
@@ -0,0 +1 @@
+See net/khttpd/README for documentation on khttpd, the kernel http server.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/pktgen.txt linux-bk/Documentation/networking/pktgen.txt
--- linux-2.4.19/Documentation/networking/pktgen.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/networking/pktgen.txt	2002-11-22 15:35:33.000000000 +0000
@@ -4,6 +4,9 @@
    in the place where insmod may find it.
 2. Cut script "ipg" (see below).
 3. Edit script to set preferred device and destination IP address.
+3a.  Create more scripts for different interfaces.  Up to thirty-two
+     pktgen processes can be configured and run at once by using the
+     32 /proc/net/pg* files.
 4. Run in shell: ". ipg"
 5. After this two commands are defined:
    A. "pg" to start generator and to get results.
@@ -12,12 +15,33 @@
       pgset "multiskb 0"      use single SKB for all transmits
       pgset "pkt_size 9014"   sets packet size to 9014
       pgset "frags 5"         packet will consist of 5 fragments
-      pgset "count 200000"    sets number of packets to send
+      pgset "count 200000"    sets number of packets to send, set to zero
+                              for continious sends untill explicitly
+                              stopped.
       pgset "ipg 5000"        sets artificial gap inserted between packets
                               to 5000 nanoseconds
       pgset "dst 10.0.0.1"    sets IP destination address
                               (BEWARE! This generator is very aggressive!)
+      pgset "dst_min 10.0.0.1"            Same as dst
+      pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
+      pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
+      pgset "src_max 10.0.0.254"          Set the maximum source IP.
       pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
+      pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
+      pgset "src_mac_count 1" Sets the number of MACs we'll range through.  The
+                              'minimum' MAC is what you set with srcmac.
+      pgset "dst_mac_count 1" Sets the number of MACs we'll range through.  The
+                              'minimum' MAC is what you set with dstmac.
+      pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
+                              are: IPSRC_RND #IP Source is random (between min/max),
+                                   IPDST_RND, UDPSRC_RND,
+                                   UDPDST_RND, MACSRC_RND, MACDST_RND 
+      pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
+                              cycle through the port range.
+      pgset "udp_src_max 9"   set UDP source port max.
+      pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
+                              cycle through the port range.
+      pgset "udp_dst_max 9"   set UDP destination port max.
       pgset stop    	      aborts injection
       
   Also, ^C aborts generator.
@@ -26,22 +50,24 @@
 
 #! /bin/sh
 
-modprobe pktgen.o
+modprobe pktgen
+
+PGDEV=/proc/net/pg/pg0
 
 function pgset() {
     local result
 
-    echo $1 > /proc/net/pg
+    echo $1 > $PGDEV
 
-    result=`cat /proc/net/pg | fgrep "Result: OK:"`
+    result=`cat $PGDEV | fgrep "Result: OK:"`
     if [ "$result" = "" ]; then
-         cat /proc/net/pg | fgrep Result:
+         cat $PGDEV | fgrep Result:
     fi
 }
 
 function pg() {
-    echo inject > /proc/net/pg
-    cat /proc/net/pg
+    echo inject > $PGDEV
+    cat $PGDEV
 }
 
 pgset "odev eth0"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/networking/tuntap.txt linux-bk/Documentation/networking/tuntap.txt
--- linux-2.4.19/Documentation/networking/tuntap.txt	2001-04-25 21:59:56.000000000 +0000
+++ linux-bk/Documentation/networking/tuntap.txt	2002-11-22 15:35:29.000000000 +0000
@@ -7,43 +7,71 @@
   FreeBSD TAP driver 
   Copyright (c) 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>
 
+  Revision of this document 2002 by Florian Thiel <florian.thiel@gmx.net>
+
 1. Description
   TUN/TAP provides packet reception and transmission for user space programs. 
-  It can be viewed as a simple Point-to-Point or Ethernet device, which 
-  instead of receiving packets from a physical media, receives them from 
+  It can be seen as a simple Point-to-Point or Ethernet device, which,
+  instead of receiving packets from physical media, receives them from 
   user space program and instead of sending packets via physical media 
   writes them to the user space program. 
 
-  When a program opens /dev/net/tun, driver creates and registers corresponding
-  net device tunX or tapX. After a program closed above devices, driver will 
-  automatically delete tunXX or tapXX device and all routes corresponding to it.
-
-  This package(http://vtun.sourceforge.net/tun) contains two simple example 
-  programs how to use tun and tap devices. Both programs works like 
-  bridge between two network interfaces.
+  In order to use the driver a program has to open /dev/net/tun and issue a
+  corresponding ioctl() to register a network device with the kernel. A network
+  device will appear as tunXX or tapXX, depending on the options chosen. When
+  the program closes the file descriptor, the network device and all
+  corresponding routes will disappear.
+
+  Depending on the type of device chosen the userspace program has to read/write
+  IP packets (with tun) or ethernet frames (with tap). Which one is being used
+  depends on the flags given with the ioctl().
+
+  The package from http://vtun.sourceforge.net/tun contains two simple examples
+  for how to use tun and tap devices. Both programs work like a bridge between
+  two network interfaces.
   br_select.c - bridge based on select system call.
   br_sigio.c  - bridge based on async io and SIGIO signal.
-  However the best example is VTun http://vtun.sourceforge.net :))  
+  However, the best example is VTun http://vtun.sourceforge.net :))
 
 2. Configuration 
   Create device node:
+     mkdir /dev/net (if it doesn't exist already)
      mknod /dev/net/tun c 10 200
+  
+  Set permissions:
+     e.g. chmod 0700 /dev/net/tun
+     if you want the device only accesible by root. Giving regular users the
+     right to assign network devices is NOT a good idea. Users could assign
+     bogus network interfaces to trick firewalls or administrators.
 
   Driver module autoloading
      Make sure that "Kernel module loader" - module auto-loading support is enabled 
      in your kernel. 
 
-     Add following line to the /etc/modules.conf:
+     Add the following line to the /etc/modules.conf:
 	alias char-major-10-200 tun
-     
-     Run:
+     and run
         depmod -a 
-
-     Driver will be automatically loaded when application access /dev/net/tun.
+  
+  Manual loading 
+     insert the module by hand:
+        modprobe tun
+
+  If you do it the latter way, you have to load the module every time you
+  need it, if you do it the other way it will be automatically loaded when
+  /dev/net/tun is being opened.
 
 3. Program interface 
   3.1 Network device allocation:
 
+  char *dev should be the name of the device with a format string (e.g.
+  "tun%d"), but (as far as I can see) this can be any valid network device name.
+  Note that the character pointer becomes overwritten with the real device name
+  (e.g. "tun0")
+
+  #include <linux/if.h>
+  #include <linux/if_tun.h>
+
   int tun_alloc(char *dev)
   {
       struct ifreq ifr;
@@ -79,65 +107,44 @@
 
 Universal TUN/TAP device driver Frequently Asked Question.
    
-1. What is the TUN ?
-The TUN is Virtual Point-to-Point network device.
-TUN driver was designed as low level kernel support for
-IP tunneling. It provides to userland application
-two interfaces:
-  - /dev/tunX	- character device;
-  - tunX	- virtual Point-to-Point interface.
-
-Userland application can write IP frame to /dev/tunX
-and kernel will receive this frame from tunX interface. 
-In the same time every frame that kernel writes to tunX 
-interface can be read by userland application from /dev/tunX
-device.
-
-2. What is the TAP ?
-The TAP is a Virtual Ethernet network device.
-TAP driver was designed as low level kernel support for
-Ethernet tunneling. It provides to userland application
-two interfaces:
-  - /dev/tapX	- character device;
-  - tapX	- virtual Ethernet interface.
-
-Userland application can write Ethernet frame to /dev/tapX
-and kernel will receive this frame from tapX interface. 
-In the same time every frame that kernel writes to tapX 
-interface can be read by userland application from /dev/tapX
-device.
-
-3. What platforms are supported by TUN/TAP driver ?
+1. What platforms are supported by TUN/TAP driver ?
 Currently driver has been written for 3 Unices:
    Linux kernels 2.2.x, 2.4.x 
    FreeBSD 3.x, 4.x, 5.x
    Solaris 2.6, 7.0, 8.0
 
-4. What is TUN/TAP driver used for?
+2. What is TUN/TAP driver used for?
 As mentioned above, main purpose of TUN/TAP driver is tunneling. 
 It is used by VTun (http://vtun.sourceforge.net).
 
-5. How does Virtual network device actually work ? 
+Another interesting application using TUN/TAP is pipsecd
+(http://perso.enst.fr/~beyssac/pipsec/), an userspace IPSec
+implementation that can use complete kernel routing (unlike FreeS/WAN).
+
+3. How does Virtual network device actually work ? 
 Virtual network device can be viewed as a simple Point-to-Point or
 Ethernet device, which instead of receiving packets from a physical 
 media, receives them from user space program and instead of sending 
 packets via physical media sends them to the user space program. 
 
 Let's say that you configured IPX on the tap0, then whenever 
-kernel sends any IPX packet to tap0, it is passed to the application
-(VTun for example). Application encrypts, compresses and sends it to 
-the other side over TCP or UDP. Application on other side decompress 
-and decrypts them and write packet to the TAP device, kernel handles 
-the packet like it came from real physical device.
+the kernel sends an IPX packet to tap0, it is passed to the application
+(VTun for example). The application encrypts, compresses and sends it to 
+the other side over TCP or UDP. The application on the other side decompresses
+and decrypts the data received and writes the packet to the TAP device, 
+the kernel handles the packet like it came from real physical device.
 
-6. What is the difference between TUN driver and TAP driver?
+4. What is the difference between TUN driver and TAP driver?
 TUN works with IP frames. TAP works with Ethernet frames.
 
-7. What is the difference between BPF and TUN/TAP driver?
-BFP is a advanced packet filter. It can be attached to existing
-network interface. It does not provide virtual network interface.
-TUN/TAP driver does provide virtual network interface and it is possible
+This means that you have to read/write IP packets when you are using tun and
+ethernet frames when using tap.
+
+5. What is the difference between BPF and TUN/TAP driver?
+BFP is an advanced packet filter. It can be attached to existing
+network interface. It does not provide a virtual network interface.
+A TUN/TAP driver does provide a virtual network interface and it is possible
 to attach BPF to this interface.
 
-8. Does TAP driver support kernel Ethernet bridging?
+6. Does TAP driver support kernel Ethernet bridging?
 Yes. Linux and FreeBSD drivers support Ethernet bridging. 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/parisc/00-INDEX linux-bk/Documentation/parisc/00-INDEX
--- linux-2.4.19/Documentation/parisc/00-INDEX	2000-12-05 20:29:38.000000000 +0000
+++ linux-bk/Documentation/parisc/00-INDEX	2002-11-22 15:35:32.000000000 +0000
@@ -1,10 +1,10 @@
 00-INDEX
 	- this file.
 IODC.txt
-	- Documentation IODC
+	- Documentation for IODC
 debugging
 	- some debugging hints for real-mode code
-mm
-	- Documentation on parisc mm status
+unwritten
+	- list of unwritten / incomplete functions
 registers
 	- current/planned usage of registers
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/parisc/registers linux-bk/Documentation/parisc/registers
--- linux-2.4.19/Documentation/parisc/registers	2001-09-14 21:04:06.000000000 +0000
+++ linux-bk/Documentation/parisc/registers	2002-11-22 15:35:22.000000000 +0000
@@ -25,8 +25,8 @@
 CR27 (TR 3)			Thread descriptor pointer
 CR28 (TR 4)			not used
 CR29 (TR 5)			not used
-CR30 (TR 6)			current / 0
-CR31 (TR 7)			Temporary register, used in various places
+CR30 (TR 6)			current
+CR31 (TR 7)			interrupt stack base
 
 	Space Registers (kernel mode)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/powerpc/00-INDEX linux-bk/Documentation/powerpc/00-INDEX
--- linux-2.4.19/Documentation/powerpc/00-INDEX	2000-06-20 14:24:52.000000000 +0000
+++ linux-bk/Documentation/powerpc/00-INDEX	2002-11-22 15:35:25.000000000 +0000
@@ -5,6 +5,9 @@
 
 00-INDEX
 	- this file
+cpu_features.txt
+	- info on how we support a variety of CPUs with minimal compile-time
+	options.
 ppc_htab.txt
 	- info about the Linux/PPC /proc/ppc_htab entry
 smp.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/powerpc/cpu_features.txt linux-bk/Documentation/powerpc/cpu_features.txt
--- linux-2.4.19/Documentation/powerpc/cpu_features.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/powerpc/cpu_features.txt	2002-11-22 15:35:24.000000000 +0000
@@ -0,0 +1,56 @@
+Hollis Blanchard <hollis@austin.ibm.com>
+5 Jun 2002
+
+This document describes the system (including self-modifying code) used in the
+PPC Linux kernel to support a variety of PowerPC CPUs without requiring
+compile-time selection.
+
+Early in the boot process the ppc32 kernel detects the current CPU type and
+chooses a set of features accordingly. Some examples include Altivec support,
+split instruction and data caches, and if the CPU supports the DOZE and NAP
+sleep modes.
+
+Detection of the feature set is simple. A list of processors can be found in
+arch/ppc/kernel/cputable.c. The PVR register is masked and compared with each
+value in the list. If a match is found, the cpu_features of cur_cpu_spec is
+assigned to the feature bitmask for this processor and a __setup_cpu function
+is called.
+
+C code may test 'cur_cpu_spec[smp_processor_id()]->cpu_features' for a
+particular feature bit. This is done in quite a few places, for example
+in ppc_setup_l2cr().
+
+Implementing cpufeatures in assembly is a little more involved. There are
+several paths that are performance-critical and would suffer if an array
+index, structure dereference, and conditional branch were added. To avoid the
+performance penalty but still allow for runtime (rather than compile-time) CPU
+selection, unused code is replaced by 'nop' instructions. This nop'ing is
+based on CPU 0's capabilities, so a multi-processor system with non-identical
+processors will not work (but such a system would likely have other problems
+anyways).
+
+After detecting the processor type, the kernel patches out sections of code
+that shouldn't be used by writing nop's over it. Using cpufeatures requires
+just 2 macros (found in include/asm-ppc/cputable.h), as seen in head.S
+transfer_to_handler:
+
+	#ifdef CONFIG_ALTIVEC
+	BEGIN_FTR_SECTION
+		mfspr	r22,SPRN_VRSAVE		/* if G4, save vrsave register value */
+		stw	r22,THREAD_VRSAVE(r23)
+	END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+	#endif /* CONFIG_ALTIVEC */
+
+If CPU 0 supports Altivec, the code is left untouched. If it doesn't, both
+instructions are replaced with nop's.
+
+The END_FTR_SECTION macro has two simpler variations: END_FTR_SECTION_IFSET
+and END_FTR_SECTION_IFCLR. These simply test if a flag is set (in
+cur_cpu_spec[0]->cpu_features) or is cleared, respectively. These two macros
+should be used in the majority of cases.
+
+The END_FTR_SECTION macros are implemented by storing information about this
+code in the '__ftr_fixup' ELF section. When do_cpu_ftr_fixups
+(arch/ppc/kernel/misc.S) is invoked, it will iterate over the records in
+__ftr_fixup, and if the required feature is not present it will loop writing
+nop's from each BEGIN_FTR_SECTION to END_FTR_SECTION.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/s390/3270.ChangeLog linux-bk/Documentation/s390/3270.ChangeLog
--- linux-2.4.19/Documentation/s390/3270.ChangeLog	2001-04-12 19:03:50.000000000 +0000
+++ linux-bk/Documentation/s390/3270.ChangeLog	2002-11-22 15:35:23.000000000 +0000
@@ -1,5 +1,34 @@
 ChangeLog for the UTS Global 3270-support patch
 
+Sep 2002:	Get bootup colors right on 3270 console
+	* In tubttybld.c, substantially revise ESC processing so that
+	  ESC sequences (especially coloring ones) and the strings
+	  they affect work as right as 3270 can get them.  Also, set
+	  screen height to omit the two rows used for input area, in
+	  tty3270_open() in tubtty.c.
+
+Sep 2002:	Dynamically get 3270 input buffer
+	* Oversize 3270 screen widths may exceed GEOM_MAXINPLEN columns,
+	  so get input-area buffer dynamically when sizing the device in
+	  tubmakemin() in tuball.c (if it's the console) or tty3270_open()
+	  in tubtty.c (if needed).  Change tubp->tty_input to be a
+	  pointer rather than an array, in tubio.h.
+
+Sep 2002:	Fix tubfs kmalloc()s
+	* Do read and write lengths correctly in fs3270_read()
+	  and fs3270_write(), whilst never asking kmalloc()
+	  for more than 0x800 bytes.  Affects tubfs.c and tubio.h.
+
+Sep 2002:	Recognize 3270 control unit type 3174
+	* Recognize control-unit type 0x3174 as well as 0x327?.
+	  The IBM 2047 device emulates a 3174 control unit.
+	  Modularize control-unit recognition in tuball.c by
+	  adding and invoking new tub3270_is_ours().
+
+Apr 2002:	Fix 3270 console reboot loop
+	* (Belated log entry) Fixed reboot loop if 3270 console,
+	  in tubtty.c:ttu3270_bh().
+
 Feb 6, 2001:
 	* This changelog is new
 	* tub3270 now supports 3270 console:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sound/Maestro3 linux-bk/Documentation/sound/Maestro3
--- linux-2.4.19/Documentation/sound/Maestro3	2001-02-04 18:05:29.000000000 +0000
+++ linux-bk/Documentation/sound/Maestro3	2002-11-22 15:35:27.000000000 +0000
@@ -71,10 +71,18 @@
 tell the driver to print minimal debugging information as it runs.  This
 can be collected with 'dmesg' or through the klogd daemon.
 
-The other is 'external_amp', which tells the driver to attempt to enable
+One is 'external_amp', which tells the driver to attempt to enable
 an external amplifier.  This defaults to '1', you can tell the driver
 not to bother enabling such an amplifier by setting it to '0'.
 
+And the last is 'gpio_pin', which tells the driver which GPIO pin number
+the external amp uses (0-15), The Allegro uses 8 by default, all others 1.
+If everything loads correctly and seems to be working but you get no sound, 
+try tweaking this value. 
+
+Systems known to need a different value
+        Panasonic ToughBook CF-72: gpio_pin=13 
+
 Power Management
 ----------------
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sound/forte linux-bk/Documentation/sound/forte
--- linux-2.4.19/Documentation/sound/forte	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/sound/forte	2002-11-22 15:35:33.000000000 +0000
@@ -0,0 +1,41 @@
+
+     forte - an OSS/Lite driver for FortéMedia FM801 sound chips
+     ===========================================================
+
+This is a driver for cards using the FortéMedia FM801 audio
+controller.  The Genius Sound Maker Live card and the onboard audio in
+HP Workstation zx2000 has been tested.
+
+Both IA-32 and IA-64 architectures are supported, but the driver
+should work on any platform.
+
+The FM801 controller supports a variety of AC'97 codecs.  This driver
+lets the OSS core code figure the codec out, and should thus support
+any codec with support in the Linux kernel.
+
+The driver supports /dev/mixer and /dev/dsp for generic OSS audio
+support.  In general it adheres to the OSS spec to the extent it can
+be done with the way the hardware works.  The FM801 controller doesn't
+support scatter-gather, so if the application sets fragment size too
+low, it puts strict requirements on interrupt processing speed.  The
+driver tries to compensate by enforcing bigger buffers than requested
+by the application if the fragment size is low.
+
+The forte driver includes both standard read()/write() and the
+unsupported mmap() interface used by Quake.  mmap() is only supported
+in playback mode.
+
+U8 and S16 audio formats are supported, mono/stereo, as well as most
+all sample rates implemented by the chip.  Default is 48 KHz, 16-bit,
+mono.
+
+MIDI, FM audio, and the gameport controller are not currently
+supported.
+
+
+The latest version of this driver can be found at:
+
+    http://mkp.net/forte/
+
+
+Martin K. Petersen, July 2002
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/sysctl/vm.txt linux-bk/Documentation/sysctl/vm.txt
--- linux-2.4.19/Documentation/sysctl/vm.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/sysctl/vm.txt	2002-11-22 15:35:32.000000000 +0000
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/vm/*	kernel version 2.2.10
+Documentation for /proc/sys/vm/*	kernel version 2.4.19
 	(c) 1998, 1999,  Rik van Riel <riel@nl.linux.org>
 
 For general info and legal blurb, please look in README.
@@ -6,7 +6,7 @@
 ==============================================================
 
 This file contains the documentation for the sysctl files in
-/proc/sys/vm and is valid for Linux kernel version 2.2.
+/proc/sys/vm and is valid for Linux kernel version 2.4.
 
 The files in this directory can be used to tune the operation
 of the virtual memory (VM) subsystem of the Linux kernel, and
@@ -34,26 +34,27 @@
 This file controls the operation of the bdflush kernel
 daemon. The source code to this struct can be found in
 linux/fs/buffer.c. It currently contains 9 integer values,
-of which 4 are actually used by the kernel.
+of which 6 are actually used by the kernel.
 
 From linux/fs/buffer.c:
 --------------------------------------------------------------
 union bdflush_param {
 	struct {
-		int nfract;	/* Percentage of buffer cache dirty to 
+		int nfract;	/* Percentage of buffer cache dirty to
 				   activate bdflush */
-		int dummy1;	/* old "ndirty" */
+		int ndirty;	/* Maximum number of dirty blocks to write out per
+				   wake-cycle */
 		int dummy2;	/* old "nrefill" */
 		int dummy3;	/* unused */
 		int interval;	/* jiffies delay between kupdate flushes */
-		int age_buffer;	/* Time for normal buffer to age */
-		int nfract_sync;/* Percentage of buffer cache dirty to 
+		int age_buffer;	/* Time for normal buffer to age before we flush it */
+		int nfract_sync;/* Percentage of buffer cache dirty to
 				   activate bdflush synchronously */
-		int dummy4;	/* unused */
+		int nfract_stop_bdflush; /* Percentage of buffer cache dirty to stop bdflush */
 		int dummy5;	/* unused */
 	} b_un;
 	unsigned int data[N_PARAM];
-} bdf_prm = {{30, 64, 64, 256, 5*HZ, 30*HZ, 60, 0, 0}};
+} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}};
 --------------------------------------------------------------
 
 int nfract:
@@ -68,6 +69,13 @@
 more frequent I/O operations.  The default value is 30%,
 the minimum is 0%, and the maximum is 100%.
 
+int ndirty:
+The second parameter (ndirty) gives the maximum number of
+dirty buffers that bdflush can write to the disk in one time.
+A high value will mean delayed, bursty I/O, while a small
+value can lead to memory shortage when bdflush isn't woken
+up often enough.
+
 int interval:
 The fifth parameter, interval, is the minimum rate at
 which kupdate will wake and flush.  The value is expressed in
@@ -88,7 +96,11 @@
 synchronously.  This can be viewed as the hard limit before
 bdflush forces buffers to disk.  The default is 60%, the
 minimum is 0%, and the maximum is 100%.
- 
+
+int nfract_stop_bdflush:
+The eighth parameter, nfract_stop_bdflush, governs the percentage
+of buffer cache that is dirty which will stop bdflush.
+The default is 20%, the miniumum is 0%, and the maxiumum is 100%.
 ==============================================================
 buffermem:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/auerswald.txt linux-bk/Documentation/usb/auerswald.txt
--- linux-2.4.19/Documentation/usb/auerswald.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/usb/auerswald.txt	2002-11-22 15:35:30.000000000 +0000
@@ -27,4 +27,4 @@
 ============
 - Connection to ISDN4LINUX (the hisax interface)
 
-The maintainer of this driver is wmues@nexgo.de
+The maintainer of this driver is wolfgang@iksw-muees.de
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/ov511.txt linux-bk/Documentation/usb/ov511.txt
--- linux-2.4.19/Documentation/usb/ov511.txt	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/Documentation/usb/ov511.txt	2002-11-22 15:35:24.000000000 +0000
@@ -128,16 +128,6 @@
         programs that expect RGB data (e.g. gqcam) to work with this driver. If
         your colors look VERY wrong, you may want to change this.
 
-  NAME: buf_timeout
-  TYPE: integer
-  DEFAULT: 5 (seconds)
-  DESC: Number of seconds before unused frame buffers are deallocated.
-        Previously, memory was allocated upon open() and deallocated upon
-        close(). Deallocation now occurs only if the driver is closed and this
-        timeout is reached. If you are capturing frames less frequently than
-        the default timeout, increase this. This will not make any difference
-        with programs that capture multiple frames during an open/close cycle.
-
   NAME: cams
   TYPE: integer (1-4 for OV511, 1-31 for OV511+)
   DEFAULT: 1
@@ -161,13 +151,6 @@
   DESC: This configures the camera's sensor to transmit a colored test-pattern
         instead of an image. This does not work correctly yet.
 
-  NAME: sensor_gbr (*** TEMPORARILY DISABLED ***)
-  TYPE: integer (Boolean)
-  DEFAULT: 0
-  DESC: This makes the sensor output GBR422 instead of YUV420. This saves the
-        driver the trouble of converting YUV to RGB, but it currently does not
-        work very well (the colors are not quite right)
-
   NAME: dumppix
   TYPE: integer (0-2)
   DEFAULT: 0
@@ -182,9 +165,9 @@
   DEFAULT: 1 (Always on)
   DESC: Controls whether the LED (the little light) on the front of the camera
 	is always off (0), always on (1), or only on when driver is open (2).
-	This is only supported with the OV511+ chipset, and even then only on
-	some cameras (ones that actually have the LED wired to the control pin,
-	and not just hardwired to be on all the time).
+	This is not supported with the OV511, and might only work with certain
+	cameras (ones that actually have the LED wired to the control pin, and
+	not just hard-wired to be on all the time).
 
   NAME: dump_bridge
   TYPE: integer (Boolean)
@@ -259,14 +242,6 @@
 		13  VIDEO_PALETTE_YUV422P   (YUV 4:2:2 Planar)
 		15  VIDEO_PALETTE_YUV420P   (YUV 4:2:0 Planar, same as 10)
 
-  NAME: tuner
-  TYPE: integer
-  DEFAULT: -1 (autodetect)
-  DESC: This sets the exact type of the tuner module in a device. This is set
-	automatically based on the custom ID of the OV511 device. In cases
-	where this fails, you can override this auto-detection. Please see
-	linux/drivers/media/video/tuner.h for a complete list.
-
   NAME: backlight
   TYPE: integer (Boolean)
   DEFAULT: 0 (off)
@@ -293,7 +268,14 @@
 	will compensate for the blocks of corruption that can appear when the
 	camera cannot keep up with the speed of the USB bus (eg. at low frame
 	resolutions). This feature is always enabled when compression is on.
- 
+
+  NAME: mirror
+  TYPE: integer (Boolean)
+  DEFAULT: 0 (off)
+  DESC: Setting this to 1 will reverse ("mirror") the image horizontally. This
+	might be necessary if your camera has a custom lens assembly. This has
+	no effect with video capture devices.
+
 WORKING FEATURES:
  o Color streaming/capture at most widths and heights that are multiples of 8.
  o RGB24, RGB565, YUV420/YUV420P, YUV422/YUYV, and YUV422P color
@@ -304,22 +286,9 @@
  o SAA7111A video capture support at 320x240 and 640x480
  o Compression support
 
-EXPERIMENTAL FEATURES:
- o OV6630 sensor support
- o Banding filter
- o SMP compatibility
-
-TO-DO:
- o V4L2 support (This will be done after the next kernel patch release)
- o Setting of hue not working with OV7620
- o Setting of contrast and hue not working with OV7620AE
- o OV8600 sensor support (Not used in anything yet)
- o OV518/OV518+ support (all that's needed is the decompressor)
- o cams >= 3 not working
-
 HOW TO CONTACT ME:
 
-You can email me at mmcclell@bigfoot.com . Please prefix the subject line
+You can email me at mark@alpha.dyndns.org . Please prefix the subject line
 with "OV511: " so that I am certain to notice your message.
 
 CREDITS:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/usb/silverlink.txt linux-bk/Documentation/usb/silverlink.txt
--- linux-2.4.19/Documentation/usb/silverlink.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/usb/silverlink.txt	2002-11-22 15:35:24.000000000 +0000
@@ -0,0 +1,76 @@
+-------------------------------------------------------------------------
+Readme for Linux device driver for the Texas Instruments SilverLink cable
+-------------------------------------------------------------------------
+
+Author: Romain Liévin & Julien Blache
+Homepage: http://lpg.ticalc.org/prj_usb
+
+INTRODUCTION:
+
+This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable 
+designed by TI for connecting their TI8x/9x calculators to a computer 
+(PC or Mac usually).
+
+If you need more information, please visit the 'SilverLink drivers' homepage 
+at the above URL.
+
+WHAT YOU NEED:
+
+A TI calculator of course and a program capable to communicate with your 
+calculator.
+TiLP will work for sure (since I am his developer !). yal92 may be able to use
+it by changing tidev for tiglusb (may require some hacking...).
+
+HOW TO USE IT:
+
+You must have first compiled USB support, support for your specific USB host
+controller (UHCI or OHCI).
+
+Next, (as root) from your appropriate modules directory (lib/modules/2.5.XX):
+
+       insmod usb/usbcore.o
+       insmod usb/usb-uhci.o  <OR>  insmod usb/ohci-hcd.o
+       insmod tiglusb.o
+
+If it is not already there (it usually is), create the device:
+
+       mknod /dev/tiglusb0 c 115 16
+
+You will have to set permissions on this device to allow you to read/write
+from it:
+
+       chmod 666 /dev/tiglusb0
+       
+Now you are ready to run a linking program such as TiLP. Be sure to configure 
+it properly (RTFM).
+       
+MODULE PARAMETERS:
+
+  You can set these with:  insmod tiglusb NAME=VALUE
+  There is currently no way to set these on a per-cable basis.
+
+  NAME: timeout
+  TYPE: integer
+  DEFAULT: 15
+  DESC: Timeout value in tenth of seconds. If no data is available once this 
+       time has expired then the driver will return with a timeout error.
+
+QUIRKS:
+
+The following problem seems to be specific to the link cable since it appears 
+on all platforms (Linux, Windows, Mac OS-X). 
+
+In some very particular cases, the driver returns with success but
+without any data. The application should retry a read operation at least once.
+
+HOW TO CONTACT US:
+
+You can email me at roms@lpg.ticalc.org. Please prefix the subject line
+with "TIGLUSB: " so that I am certain to notice your message.
+You can also mail JB at jb@jblache.org: he has written the first release of 
+this driver but he better knows the Mac OS-X driver.
+
+CREDITS:
+
+The code is based on dabusb.c, printer.c and scanner.c !
+The driver has been developed independantly of Texas Instruments.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/CARDLIST linux-bk/Documentation/video4linux/bttv/CARDLIST
--- linux-2.4.19/Documentation/video4linux/bttv/CARDLIST	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/CARDLIST	2002-11-22 15:35:24.000000000 +0000
@@ -3,41 +3,41 @@
   card=1 - MIRO PCTV
   card=2 - Hauppauge (bt848)
   card=3 - STB
-  card=4 - Intel
+  card=4 - Intel Create and Share PCI/ Smart Video Recorder III
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - FlyVideo II (Bt848) LR26
-  card=9 - IXMicro TurboTV
+  card=8 - Lifeview FlyVideo II (Bt848) LR26
+  card=9 - IMS/IXmicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
-  card=12 - ADS Technologies Channel Surfer TV
+  card=12 - ADS Technologies Channel Surfer TV (bt848)
   card=13 - AVerMedia TVCapture 98
   card=14 - Aimslab Video Highway Xtreme (VHX)
   card=15 - Zoltrix TV-Max
-  card=16 - Pixelview PlayTV (bt878)
+  card=16 - Prolink Pixelview PlayTV (bt878)
   card=17 - Leadtek WinView 601
   card=18 - AVEC Intercapture
-  card=19 - LifeView FlyKit w/o Tuner
+  card=19 - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)
   card=20 - CEI Raffles Card
-  card=21 - Lucky Star Image World ConferenceTV
-  card=22 - Phoebe Tv Master + FM (CPH050)
+  card=21 - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50
+  card=22 - Askey CPH050/ Phoebe Tv Master + FM
   card=23 - Modular Technology MM205 PCTV, bt878
-  card=24 - [many vendors] CPH05X/06X (bt878)
-  card=25 - Terratec/Vobis TV-Boostar
-  card=26 - Newer Hauppauge WinCam (bt878)
-  card=27 - MAXI TV Video PCI2
+  card=24 - Askey CPH05X/06X (bt878) [many vendors]
+  card=25 - Terratec Terra TV+ Version 1.0 (Bt848)/Vobis TV-Boostar
+  card=26 - Hauppauge WinCam newer (bt878)
+  card=27 - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50
   card=28 - Terratec TerraTV+
   card=29 - Imagenation PXC200
-  card=30 - FlyVideo 98
-  card=31 - iProTV
-  card=32 - Intel Create and Share PCI
+  card=30 - Lifeview FlyVideo 98 LR50
+  card=31 - Formac iProTV
+  card=32 - Intel Create and Share PCI/ Smart Video Recorder III
   card=33 - Terratec TerraTValue
   card=34 - Leadtek WinFast 2000
-  card=35 - Flyvideo 98 (LR50Q) / Chronos Video Shuttle II
-  card=36 - Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner
-  card=37 - PixelView PlayTV pro
-  card=38 - TView99 CPH06X
+  card=35 - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II
+  card=36 - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner
+  card=37 - Prolink PixelView PlayTV pro
+  card=38 - Askey CPH06X TView99
   card=39 - Pinnacle PCTV Studio/Rave
   card=40 - STB2
   card=41 - AVerMedia TVPhone 98
@@ -47,45 +47,47 @@
   card=45 - MATRIX-Vision MV-Delta 2
   card=46 - Zoltrix Genie TV/FM
   card=47 - Terratec TV/Radio+
-  card=48 - Dynalink Magic TView 
-  card=49 - GV-BCTV3
+  card=48 - Askey CPH03x/ Dynalink Magic TView
+  card=49 - IODATA GV-BCTV3/PCI
   card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
   card=51 - Eagle Wireless Capricorn2 (bt878A)
   card=52 - Pinnacle PCTV Studio Pro
   card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
-  card=54 - Lifetec LT 9415 TV (LR90 Rev.F)
-  card=55 - BESTBUY Easy TV (CPH031)
-  card=56 - FlyVideo '98/FM
+  card=54 - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]
+  card=55 - Askey CPH031/ BESTBUY Easy TV
+  card=56 - Lifeview FlyVideo 98FM LR50
   card=57 - GrandTec 'Grand Video Capture' (Bt848)
-  card=58 - Phoebe TV Master Only (No FM) CPH060
-  card=59 - TV Capturer (CPH03X)
+  card=58 - Askey CPH060/ Phoebe TV Master Only (No FM)
+  card=59 - Askey CPH03x TV Capturer
   card=60 - Modular Technology MM100PCTV
   card=61 - AG Electronics GMV1
-  card=62 - BESTBUY Easy TV (bt878)
+  card=62 - Askey CPH061/ BESTBUY Easy TV (bt878)
   card=63 - ATI TV-Wonder
   card=64 - ATI TV-Wonder VE
-  card=65 - FlyVideo 2000S
+  card=65 - Lifeview FlyVideo 2000S LR90
   card=66 - Terratec TValueRadio
-  card=67 - GV-BCTV4/PCI
+  card=67 - IODATA GV-BCTV4/PCI
   card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)
   card=69 - Active Imaging AIMMS
-  card=70 - PV-BT878P+
-  card=71 - Flyvideo 98EZ (capture only)
-  card=72 - Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
+  card=70 - Prolink Pixelview PV-BT878P+ (Rev.4C)
+  card=71 - Lifeview FlyVideo 98EZ (capture only) LR51
+  card=72 - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
   card=73 - Sensoray 311
   card=74 - RemoteVision MX (RV605)
   card=75 - Powercolor MTV878/ MTV878R/ MTV878F
   card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
   card=77 - GrandTec Multi Capture Card (Bt878)
-  card=78 - AOPEN VA1000
+  card=78 - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF
+  card=79 - DSP Design TCVIDEO
+  card=80 - Hauppauge WinTV PVR
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
-  type=1 - Philips PAL_I
-  type=2 - Philips NTSC
-  type=3 - Philips SECAM
+  type=1 - Philips PAL_I (FI1246 and compatibles)
+  type=2 - Philips NTSC (FI1236 and compatibles)
+  type=3 - Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)
   type=4 - NoTuner
-  type=5 - Philips PAL
+  type=5 - Philips PAL_BG (FI1216 and compatibles)
   type=6 - Temic NTSC (4032 FY5)
   type=7 - Temic PAL_I (4062 FY5)
   type=8 - Temic NTSC (4036 FY5)
@@ -103,7 +105,7 @@
   type=20 - Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)
   type=21 - Temic NTSC (4039 FR5)
   type=22 - Temic PAL/SECAM multi (4046 FM5)
-  type=23 - Philips PAL_DK
+  type=23 - Philips PAL_DK (FI1256 and compatibles)
   type=24 - Philips PAL/SECAM multi (FQ1216ME)
   type=25 - LG PAL_I+FM (TAPC-I001D)
   type=26 - LG PAL_I (TAPC-I701D)
@@ -118,3 +120,5 @@
   type=35 - Temic PAL_DK/SECAM_L (4012 FY5)
   type=36 - Temic NTSC (4136 FY5)
   type=37 - LG PAL (newer TAPC series)
+  type=38 - Philips PAL/SECAM multi (FM1216ME MK3)
+  type=39 - LG NTSC (newer TAPC series)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Cards linux-bk/Documentation/video4linux/bttv/Cards
--- linux-2.4.19/Documentation/video4linux/bttv/Cards	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/Cards	2002-11-22 15:35:25.000000000 +0000
@@ -1,3 +1,8 @@
+
+Gunther Mayer's bttv card gallery (graphical version of this text file :-)
+is available at: http://mayerg.gmxhome.de/bttv/bttv-gallery.html
+
+
 Suppported cards:
 
 
@@ -91,10 +96,9 @@
 - sound decoder: TDA9800, MSP34xx (stereo cards) 
 
 
-CPH-Series (CPH050, ...)
-------------------------
-Developed by TelSignal(?), OEMed by many vendors (Askey, Typhoon, 
-  Anubis, Dynalink)
+Askey CPH-Series
+----------------
+Developed by TelSignal(?), OEMed by many vendors (Typhoon, Anubis, Dynalink)
 
   Card series:
     CPH01x: BT848 capture only
@@ -149,9 +153,13 @@
       LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
            Rev.W = Flyvideo 98 (no eeprom)
       LR51 Rev.E = Flyvideo 98 EZ (capture only)
-      LR90       = Flyvideo 2000 series
+      LR90       = Flyvideo 2000 (Bt878)
+		   Flyvideo 2000S (Bt878) w/Stereo TV (Package incl. LR91 daughterboard)
       LR91       = Stereo daughter card for LR90
       LR97       = Flyvideo DVBS
+      LR99 Rev.E = Low profile card for OEM integration (only internal audio!) bt878
+      LR136	 = Flyvideo 2100/3100 (Low profile, SAA7130/SAA7134)
+      LR137      = Flyvideo DV2000/DV3000 (SAA7130/SAA7134 + IEEE1394)
       LR138 Rev.C= Flyvideo 2000 (SAA7130)
 	        or Flyvideo 3000 (SAA7134) w/Stereo TV
 		   These exist in variations w/FM and w/Remote sometimes denoted
@@ -162,15 +170,14 @@
       Their Bt8x8 cards are listed as discontinued.
       Flyvideo 2000S was probably sold as Flyvideo 3000 in some contries(Europe?).
       The new Flyvideo 2000/3000 are SAA7130/SAA7134 based. 
-      Flyvideo 2100/3100 are half-sized cards (for system integrators etc.)
 
   "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
   this name is re-used for LR50 Rev.W.
   The Lifeview website mentioned Flyvideo III at some time, but such a card
-  has never been seen. 
+  has not yet been seen (perhaps it was the german name for LR90 [stereo]).
   These cards are sold by many OEMs too.
 
-  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821)
+  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821) {Germany}
 
 
 Typhoon TV card series:
@@ -190,7 +197,12 @@
   50686 "TV Tuner"                       = KNC1 TV Station
   50687 "TV Tuner stereo"                = KNC1 TV Station pro
   50688 "TV Tuner RDS" (black package)   = KNC1 TV Station RDS
+  50689  TV SAT DVB-S CARD CI PCI (SAA7146AH)
   50692 "TV/FM Tuner" (small PCB)
+  50694  TV TUNER CARD RDS (PHILIPS CHIPSET SAA7134HL)
+  50696  TV TUNER STEREO (PHILIPS CHIPSET SAA7134HL, MK3ME Tuner)
+  50804  PC-SAT TV/Audio Karte = Techni-PC-Sat (ZORAN 36120PQC, Tuner:Alps)
+  50866  TVIEW SAT RECEIVER+ADR
   50868 "TV/FM Tuner Pal I" (variant of 50682)
   50999 "TV/FM Tuner Secam" (variant of 50682)
 
@@ -207,16 +219,31 @@
 
 Prolink
 -------
-   Pixelview Play TV Pro:
-     PV-BT878P+rev.9B (Play TV Pro w/FM w/NICAM)
-     PV-BT878P+rev.8X 
-     PV-BT878P+rev.4C (Play TV Pro) 
-     PV-BT878P+rev.4E (Play TV Pak) 
-     PV-BT878P+rev.2F 
-     PV-BT878TV 
-
-   PixelView Play TV 
-     PV-BT848P+
+   TV cards:
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 8E)
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 9D)
+   PixelView Play TV pro - (Model: PV-BT878P+ REV 4C / 8D / 10A )
+   PixelView Play TV - (Model: PV-BT848P+)
+   878TV - (Model: PV-BT878TV)
+
+   Multimedia TV packages (card + software pack):
+   PixelView Play TV Theater - (Model: PV-M4200) =  PixelView Play TV pro + Software
+   PixelView Play TV PAK -     (Model: PV-BT878P+ REV 4E)
+   PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A ) 
+   PixelView Studio PAK -      (Model:    M2200 REV 4C / 8D / 10A )
+   PixelView PowerStudio PAK - (Model: PV-M3600 REV 4E)
+   PixelView DigitalVCR PAK -  (Model: PV-M2400 REV 4C / 8D / 10A )
+
+   Further Cards:
+   PV-BT878P+rev.9B (Play TV Pro, opt. w/FM w/NICAM)
+   PV-BT878P+rev.2F
+   PV-BT878P Rev.1D (bt878, capture only)
+   
+   Video Conferencing:
+   PixelView Meeting PAK - (Model: PV-BT878P)
+   PixelView Meeting PAK Lite - (Model: PV-BT878P)
+   PixelView Meeting PAK plus - (Model: PV-BT878P+rev 4C/8D/10A)
+   PixelView Capture - (Model: PV-BT848P)
 
 Dynalink
 --------
@@ -235,7 +262,7 @@
 Tekram
 ------
    VideoCap C205 (Bt848)
-   VideoCap C210 (Zoran ZR36120 +Philips)
+   VideoCap C210 (zr36120 +Philips)
    CaptureTV M200 (ISA)
    CaptureTV M205 (Bt848)
 
@@ -257,8 +284,10 @@
    TV-Station FM (+Radio)
    TV-Station RDS (+RDS)
 
-PV951 cards:
-------------
+   newer Cards have saa7134, but model name stayed the same?
+
+Provideo PV951 
+--------------
   These are sold as:
    Boeder TV-FM Video Capture Card
    Titanmedia Supervision TV-2400
@@ -270,12 +299,14 @@
 Highscreen
 ----------
    TV Karte = LR50 Rev.S
-   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, TDA9821) "ceb105.pcb"
+   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, tda9821) "ceb105.pcb"
 
 Zoltrix
 -------
+   Face to Face Capture (Bt848 capture only) (PCB "VP-2848")
    Face To Face TV MAX (Bt848) (PCB "VP-8482 Rev1.3")
    Genie TV (Bt878) (PCB "VP-8790 Rev 2.1")
+   Genie Wonder Pro
 
 AVerMedia
 ---------
@@ -302,21 +333,24 @@
 
 Aimslab
 -------
+   Video Highway or "Video Highway TR200" (ISA)
    Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
 
-IXMicro
+IXMicro (former: IMS=Integrated Micro Solutions)
 -------
    IXTV BT848
    IXTV BT878
    TurboTV (Bt848)
 
 Lifetec/Medion/Tevion/Aldi
--------
-   LT9415/MD9415 = LR90 Rev. F
+--------------------------
+   LT9306/MD9306 = CPH061
+   LT9415/MD9415 = LR90 Rev.F or Rev.G
           MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
+          MD9717 = KNC One (Rev D4, saa7134)
 
 Modular Technologies (www.modulartech.com) UK
---------------------
+---------------------------------------------
    MM100 PCTV (Bt848)
    MM205 PCTV (Bt878)
    MM210 PCTV (Bt878) (Galaxy TV)
@@ -326,19 +360,28 @@
    Terra TV+ Version 1.0 (Bt848), "ceb105.PCB" printed on the PCB, TDA9821
    Terra TV+ Version 1.1 (Bt878), "LR74 Rev.E" printed on the PCB, TDA9821
    Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
-   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB, i
+   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB,
 				     "CPH010-E83" on the back, SAA6588T, TDA9873H
    Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB, 
 				     "CPH011-D83" on back
    Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
+   Terra Active Radio Upgrade (tea5757h, saa6588t)
 
    LR74 is a newer PCB revision of ceb105 (both incl. connector for Active Radio Upgrade)
 
+   Cinergy 400 (saa7134), "E877 11(S)", "PM820092D" printed on PCB
 
 Technisat
 ---------
-   Mediafocus I (ZR36120/ZR36125)
-   Mediafocus II (SAA7146)
+   Discos ADR PC-Karte ISA (no TV!)
+   Discos ADR PC-Karte PCI (probably no TV?)
+   Techni-PC-Sat (Sat. analog)
+         Rev 1.2 (zr36120, vpx3220, stv0030, saa5246, BSJE3-494A)
+   Mediafocus I (zr36120/zr36125, drp3510, Sat. analog + ADR Radio)
+   Mediafocus II (saa7146, Sat. analog)
+         SatADR Rev 2.1 (saa7146a, saa7113h, stv0056a, msp3400c, drp3510a, BSKE3-307A)
+   SkyStar 1 DVB  (AV7110)
+   SkyStar 2 DVB  (B2C2) (=Sky2PC)
 
 Siemens
 -------
@@ -359,34 +402,262 @@
    Mirovideo PCTV (Bt848)
    Mirovideo PCTV SE (Bt848)
    Mirovideo PCTV Pro (Bt848 + Daughterboard)
-   Studio PCTV Rave (Bt878 w/o infrared)
-   Studio PCTV
-   Studio PCTV Pro (Bt878 stereo w/ FM)
+   Studio PCTV Rave (Bt878 package w/o infrared)
+   Studio PCTV      (Bt878)
+   Studio PCTV Pro  (Bt878 stereo w/ FM)
 
+   M(J)PEG capture and playback:
    DC1+ (ISA)
-   DC10  (zr36057 + zr36060 + saa7110 + adv7176)
-   DC10+ (zr36067 + zr36060 + saa7110 + adv7176)
-   DC20
-   DC30
-   DC30+ (zr36067 + zr36050 + zr36016 + vpx3220 + adv7176)
+   DC10  (zr36057,     zr36060,      saa7110, adv7176)
+   DC10+ (zr36067,     zr36060,      saa7110, adv7176)
+   DC20  (ql16x24b,zr36050, zr36016, saa7110, saa7187 ...)
+   DC30  (zr36057, zr36050, zr36016, vpx3220, adv7176, ad1843, tea6415, miro FST97A1)
+   DC30+ (zr36067, zr36050, zr36016, vpx3220, adv7176)
+   DC50  (zr36067, zr36050, zr36016, saa7112, adv7176 (2 pcs.?), ad1843, miro FST97A1, Lattice ???)
 
 Lenco
 -----
    MXR-9565 (=Technisat Mediafocus?)
-   MXR-9571 (Bt848)
+   MXR-9571 (Bt848) (=CPH031?)
    MXR-9575
-   MXR-9477 (Bt878)
-   MXTV-9578CP (= Prolink PV-BT878P+4E)
+   MXR-9577 (Bt878) (=Prolink 878TV Rev.3x)
+   MXTV-9578CP (Bt878) (= Prolink PV-BT878P+4E)
 
 Iomega
 ------
-   Buz (Zoran zr36067 + zr36060 + SAA7111 + SAA7185)
+   Buz (zr36067, zr36060, saa7111, saa7185)
 
 LML
 ---
-   LML33 (zr36067 + zr36060 + bt819+ bt856)
+   LML33 (zr36067, zr36060, bt819, bt856)
 
 Grandtec
 --------
    Grand Video Capture (Bt848)
    Multi Capture Card  (Bt878)
+
+Koutech
+-------
+   KW-606 (Bt848)
+   KW-607 (Bt848 capture only)
+   KW-606RSF
+   KW-607A (capture only)
+   KW-608 (Zoran capture only)
+ 
+IODATA (jp)
+------
+   GV-BCTV/PCI
+   GV-BCTV2/PCI
+   GV-BCTV3/PCI
+   GV-BCTV4/PCI
+   GV-VCP/PCI (capture only)
+   GV-VCP2/PCI (capture only)
+
+Canopus (jp)
+-------
+   WinDVR	= Kworld "KW-TVL878RF"
+
+www.sigmacom.co.kr 
+------------------
+   Sigma Cyber TV II 
+
+www.sasem.co.kr
+---------------
+   Litte OnAir TV
+
+hama 
+----
+   TV/Radio-Tuner Card, PCI (Model 44677) = CPH051
+
+Sigma Designs
+-------------
+   Hollywood plus (em8300, em9010, adv7175), (PCB "M340-10") MPEG DVD decoder
+
+Formac
+------
+   iProTV (Card for iMac Mezzanine slot, Bt848+SCSI)
+   ProTV (Bt848)
+   ProTV II = ProTV Stereo (Bt878)
+
+ATI
+---
+   TV-Wonder
+   TV-Wonder VE
+
+Diamond Multimedia
+------------------
+   DTV2000 (Bt848, tda9875)
+
+Aopen
+-----
+   VA1000 Plus (w/ Stereo)
+   VA1000 Lite
+   VA1000 (=LR90)
+
+Intel
+-----
+   Smart Video Recorder (ISA full-length)
+   Smart Video Recorder pro (ISA half-length)
+   Smart Video Recorder III (Bt848)
+
+STB
+---
+   TV PCI (Temic4032FY5, tda9850??)
+   other variants?
+
+Videologic
+----------
+   Captivator Pro/TV (ISA?)
+   Captivator PCI/VC (Bt848 bundled with camera) (capture only)
+
+Technotrend
+------------
+   TT-SAT PCI (PCB "Sat-PCI Rev.:1.3.1"; zr36125, vpx3225d, stc0056a, Tuner:BSKE6-155A
+   TT-DVB-Sat
+   TT-DVB-C PCI
+
+Teles
+-----
+   DVB-s (Rev. 2.2, BSRV2-301A, data only?)
+
+Remote Vision
+-------------
+   MX RV605 (Bt848 capture only)
+
+Boeder
+------
+   PC ChatCam (Model 68252) (Bt848 capture only)
+   Tv/Fm Capture Card  (Model 68404) = PV951
+
+Media-Surfer  (esc-kathrein.de)
+-------------------------------
+   Sat-Surfer (ISA)
+   Sat-Surfer PCI = Techni-PC-Sat
+   Cable-Surfer 1
+   Cable-Surfer 2
+   Cable-Surfer PCI (zr36120)
+   Audio-Surfer (ISA Radio card)
+
+Jetway (www.jetway.com.tw)
+--------------------------
+   JW-TV 878M 
+   JW-TV 878  = KWorld KW-TV878RF
+
+Galaxis
+-------
+   Galaxis DVB Card S CI
+   Galaxis DVB Card C CI
+   Galaxis DVB Card S
+   Galaxis DVB Card C
+
+Hauppauge
+---------
+   many many WinTV models ...
+   WinTV DVBs
+   WinTV NOVA
+   WinTV NOVA-CI
+   WinTV-Nexus-s
+
+Matrix-Vision
+-------------
+   MATRIX-Vision MV-Delta
+   MATRIX-Vision MV-Delta 2
+   MVsigma-SLC (Bt848)
+
+Conceptronic (.net)
+------------
+   TVCON FM,  TV card w/ FM = CPH05x
+
+BestData
+--------
+   HCC100 = VCC100rev1 + camera
+   VCC100 rev1 (bt848)
+   VCC100 rev2 (bt878)
+
+Gallant  (www.gallantcom.com) www.minton.com.tw
+-----------------------------------------------
+   Intervision IV-510 (capture only bt8x8)
+   Intervision IV-550 (bt8x8)
+   Intervision IV-100 (zoran)
+   Intervision IV-1000 (bt8x8)
+   
+Asonic (www.asonic.com.cn) (website down)
+-----------------------------------------
+   SkyEye tv 878
+
+Hoontech
+--------
+   878TV/FM
+
+Teppro (www.itcteppro.com.tw)
+-----------------------------
+   ITC PCITV (Card Ver 1.0) "Teppro TV1/TVFM1 Card"
+   ITC PCITV (Card Ver 2.0)
+   ITC PCITV (Card Ver 3.0) = "PV-BT878P+ (REV.9D)"
+   ITC PCITV (Card Ver 4.0)
+   TEPPRO IV-550 (For BT848 Main Chip)
+   ITC DSTTV (bt878, satellite)
+   ITC VideoMaker (saa7146, StreamMachine sm2110, tvtuner) "PV-SM2210P+ (REV:1C)"
+
+Kworld (www.kworld.com.tw)
+--------------------------
+   KWORLD KW-TV878RF-Pro TV Capture with FM Radio
+   KWORLD KW-TV878R-Pro TV
+   KWORLD KW-TVL878RF  (low profile)
+   KWORLD KW-TV878R TV Capture (No FM Radio)
+   KWORLD KW-TV878RF TV
+
+JTT/ Justy Corp.http://www.justy.co.jp/ (www.jtt.com.jp website down)
+---------------------------------------------------------------------
+   JTT-02 (JTT TV) "TV watchmate pro" (bt848) 
+
+ADS www.adstech.com
+-------------------
+   Channel Surfer TV ( CHX-950 ) 
+   Channel Surfer TV+FM ( CHX-960FM )
+
+AVEC www.prochips.com
+---------------------
+   AVEC Intercapture (bt848, tea6320)
+
+NoBrand
+-------
+   TV Excel = Australian Name for "PV-BT878P+ 8E" or so
+
+Mach www.machspeed.com
+----
+   Mach TV 878
+
+Eline www.eline-net.com/
+-----
+   Eline Vision TVMaster / TVMaster FM (ELV-TVM/ ELV-TVM-FM) = LR26  (bt878)
+   Eline Vision TVMaster-2000 (ELV-TVM-2000, ELV-TVM-2000-FM)= LR138 (saa713x)
+
+Spirit http://www.spiritmodems.com.au/
+------
+   Spirit TV Tuner/Video Capture Card (bt848)
+
+Boser www.boser.com.tw
+-----
+   HS-878 Mini PCI Capture Add-on Card
+   HS-879 Mini PCI 3D Audio and Capture Add-on Card (w/ ES1938 Solo-1)
+
+Satelco
+-------
+   TV-FM =KNC1 saa7134
+
+Sensoray www.sensoray.com
+--------
+   Sensoray 311 (PC/104 bus)
+   Sensoray 611 (PCI)
+
+CEI (Chartered Electronics Industries Pte Ltd [CEI] [FCC ID HBY])
+---
+  TV Tuner  -  HBY-33A-RAFFLES  Brooktree Bt848KPF + Philips
+  TV Tuner MG9910  -  HBY33A-TVO  CEI + Philips SAA7110 + OKI M548262 + ST STV8438CV
+  Primetime TV (ISA)
+   acquired by Singapore Technologies
+   now operating as Chartered Semiconductor Manufacturing
+   Manufacturer of video cards is listed as:
+   Cogent Electronics Industries [CEI]
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Insmod-options linux-bk/Documentation/video4linux/bttv/Insmod-options
--- linux-2.4.19/Documentation/video4linux/bttv/Insmod-options	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/Insmod-options	2002-11-22 15:35:24.000000000 +0000
@@ -29,7 +29,7 @@
 		irq_debug=0/1	irq handler debug messages.
 				default is 0 (off).
 		gbuffers=2-32	number of capture buffers for mmap'ed capture.
-				default is 2.
+				default is 4.
 		gbufsize=	size of capture buffers. default and
 				maximum value is 0x208000 (~2MB)
 		no_overlay=0	Enable overlay on broken hardware.  There
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/README linux-bk/Documentation/video4linux/bttv/README
--- linux-2.4.19/Documentation/video4linux/bttv/README	2001-08-05 20:15:05.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/README	2002-11-22 15:35:23.000000000 +0000
@@ -58,6 +58,9 @@
 		the helper modules.
 MAKEDEV:	a script to create the special files for v4l
 CARDLIST:	List of all supported cards
+Cards:		more detailed descriptions of known TV cards:
+		OEM name variants, used i2c chips, ...
+		also includes non-bttv cards.
 
 Loading just the bttv modules isn't enouth for most cards.  The
 drivers for the i2c tuner/sound chips must also be loaded.  bttv tries
@@ -73,6 +76,12 @@
 video but no sound you've very likely specified the wrong (or no)
 card type.  A list of supported cards is in CARDLIST.
 
+For the WinTV/PVR you need one firmware file from the driver CD:
+hcwamc.rbf.  The file is in the pvr45xxx.exe archive (self-extracting
+zip file, unzip can unpack it).  Put it into the /etc/pvr directory or
+use the firm_altera=<path> insmod option to point the driver to the
+location of the file.
+
 If your card isn't listed in CARDLIST or if you have trouble making
 audio work, you should read the Sound-FAQ.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/README.freeze linux-bk/Documentation/video4linux/bttv/README.freeze
--- linux-2.4.19/Documentation/video4linux/bttv/README.freeze	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/README.freeze	2002-11-22 15:35:26.000000000 +0000
@@ -46,6 +46,11 @@
 the PCI bus. The bt848/878 chips have a few workarounds for known
 incompatibilities, see README.quirks.
 
+Some folks report that increasing the pci latency helps too,
+althrought I'm not sure whenever this really fixes the problems or
+only makes it less likely to happen.  Both bttv and btaudio have a
+insmod option to set the PCI latency of the device.
+
 Some mainboard have problems to deal correctly with multiple devices
 doing DMA at the same time.  bttv + ide seems to cause this sometimes,
 if this is the case you likely see freezes only with video and hard disk
@@ -56,6 +61,9 @@
 other
 -----
 
+If you use some binary-only yunk (like nvidia module) try to reproduce
+the problem without.
+
 IRQ sharing is known to cause problems in some cases.  It works just
 fine in theory and many configurations.  Neverless it might be worth a
 try to shuffle around the PCI cards to give bttv another IRQ or make
@@ -63,3 +71,4 @@
 VGA cards seems to cause trouble sometimes.  I've also seen funny
 effects with bttv sharing the IRQ with the ACPI bridge (and
 apci-enabled kernel).
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/bttv/Tuners linux-bk/Documentation/video4linux/bttv/Tuners
--- linux-2.4.19/Documentation/video4linux/bttv/Tuners	2001-10-17 21:19:20.000000000 +0000
+++ linux-bk/Documentation/video4linux/bttv/Tuners	2002-11-22 15:35:22.000000000 +0000
@@ -1,3 +1,16 @@
+1) Tuner Programming
+====================
+There are some flavors of Tuner programming APIs.
+These differ mainly by the bandswitch byte.
+
+    L= LG_API       (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
+    P= PHILIPS_API  (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
+    T= TEMIC_API    (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
+    A= ALPS_API     (VHF_LO=0x14, VHF_HI=0x12, UHF=0x11)
+    M= PHILIPS_MK3  (VHF_LO=0x01, VHF_HI=0x02, UHF=0x04, radio=0x19)
+
+2) Tuner Manufacturers
+======================
 
 SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
   TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
@@ -10,6 +23,7 @@
    M= BG+I+DK
    N= NTSC 
    Q= BG+I+DK+LL
+ [89]: ?
  [125]:
    2: No FM
    5: With FM
@@ -23,43 +37,49 @@
  [ABCD]:
    3-wire/I2C tuning, 2-band/3-band
 
+ These Tuners are PHILIPS_API compatible.
+
 Philips Tuner identification: (e.g. FM1216MF)
-  F[IRMQ]12[1345]{MF|ME|MP}
-  [IRMQ]:
-   I: Tuner Series
-   R: Tuner + Radio IF
-   M: Tuner + FM
-   Q,MR: specials
+  F[IRMQ]12[1345]6{MF|ME|MP}
+  F[IRMQ]:
+   FI12x6: Tuner Series
+   FR12x6: Tuner + Radio IF
+   FM12x6: Tuner + FM
+   FQ12x6: special
+   FMR12x6: special
    TD15xx: Digital Tuner ATSC
-  [1345]
-   1: PAL BG
-   3: NTSC
-   4: PAL I
-   5: Pal DK
+  12[1345]6:
+   1216: PAL BG
+   1236: NTSC
+   1246: PAL I
+   1256: Pal DK
   {MF|ME|MP}
-   MF: w/ Secam
-   ME: BD DK I LL
-   MP: BG DK I
+   MF: BG LL w/ Secam (Multi France)
+   ME: BG DK I LL   (Multi Europe)
+   MP: BG DK I      (Multi PAL)
    MR: BG DK M (?)
    MG: BG DKI M (?)
+  MK2 series PHILIPS_API, most tuners are compatible to this one !
+  MK3 series introduced in 2002 w/ PHILIPS_MK3_API
 
 Temic Tuner identification: (.e.g 4006FH5)
    4[01][0136][269]F[HYNR]5
-    40x2: Tuner (5V/33V), different I2C programming from Philips !
+    40x2: Tuner (5V/33V), TEMIC_API.
     40x6: Tuner 5V
     41xx: Tuner compact
     40x9: Tuner+FM compact
    [0136]
-    0: PAL BG
-    1: Pal DK, Secam LL
-    3: NTSC
-    6: PAL I
+    xx0x: PAL BG
+    xx1x: Pal DK, Secam LL
+    xx3x: NTSC
+    xx6x: PAL I
    F[HYNR]5
     FH5: Pal BG
     FY5: others
     FN5: multistandard
     FR5: w/ FM radio
    3X xxxx: order number with specific connector
+  Note: Only 40x2 series has TEMIC_API, all newer tuners have PHILIPS_API.
 
 LG Innotek Tuner:
   TPI8NSR11 : NTSC J/M    (TPI8NSR01 w/FM)  (P,210/497)
@@ -76,13 +96,20 @@
   TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
   TADC-M201D: PAL D/K+B/G+I (L,143/425)  (sound control at I2C address 0xc8)
   TADC-T003F: NTSC Taiwan  (L,175/410?; 2-B, C-W+11, W+12-69)
-
-  (API,Lo-Hi-takeover/Hi-UHF-takeover)
-   I2C APIs:
-    L= LG programming (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
-    P= Philips progr. (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
-    T= Temic progr.   (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
   Suffix: 
     P= Standard phono female socket
     D= IEC female socket
     F= F-connector
+
+Other Tuners:
+TCL2002MB-1 : PAL BG + DK       =TUNER_LG_PAL_NEW_TAPC
+TCL2002MB-1F: PAL BG + DK w/FM  =PHILIPS_PAL
+TCL2002MI-2 : PAL I		= ??
+
+ALPS Tuners:
+   Most are LG_API compatible
+   TSCH6 has ALPS_API (TSCH5 ?)
+   TSBE1 has extra API 05,02,08 Control_byte=0xCB Source:(1)
+
+Lit.
+(1) conexant100029b-PCI-Decoder-ApplicationNote.pdf
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/video4linux/meye.txt linux-bk/Documentation/video4linux/meye.txt
--- linux-2.4.19/Documentation/video4linux/meye.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/Documentation/video4linux/meye.txt	2002-11-22 15:35:25.000000000 +0000
@@ -86,7 +86,7 @@
 
 	MEYEIOC_SYNC
 		Takes as an argument the buffer number you want to sync.
-		This ioctl blocks untils the buffer is filled and ready
+		This ioctl blocks until the buffer is filled and ready
 		for the application to use. It returns the buffer size.
 
 	MEYEIOC_STILLCAPT
@@ -106,7 +106,7 @@
 		
 	- mjpeg hardware playback doesn't work (depends on overlay...)
 
-	- rewrite the driver to use some commun video4linux API for snapshot
+	- rewrite the driver to use some common video4linux API for snapshot
 	  and mjpeg capture. Unfortunately, video4linux1 does not permit it,
 	  the BUZ API seems to be targeted to TV cards only. The video4linux 2
 	  API may be an option, if it goes into the kernel (maybe 2.5 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/x86_64/BUGS linux-bk/Documentation/x86_64/BUGS
--- linux-2.4.19/Documentation/x86_64/BUGS	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/x86_64/BUGS	2002-11-22 15:35:25.000000000 +0000
@@ -0,0 +1,10 @@
+Some known problems:
+
+-- Compiling the kernel with -j for parallel makes is not completely safe
+due to missing dependencies with offset.h. Usually it is safe when it 
+already exists, but not always.
+
+Current hack is to rerun make depend manually when you change anything
+that would touch offset.h (see arch/x86-64/tools/offset.c on what that is).
+Do not use -j with depend. 
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Documentation/x86_64/mm.txt linux-bk/Documentation/x86_64/mm.txt
--- linux-2.4.19/Documentation/x86_64/mm.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/Documentation/x86_64/mm.txt	2002-11-22 15:35:26.000000000 +0000
@@ -0,0 +1,194 @@
+The paging design used on the x86-64 linux kernel port in 2.4.x provides:
+
+o	per process virtual address space limit of 512 Gigabytes
+o	top of userspace stack located at address 0x0000007fffffffff
+o	PAGE_OFFSET = 0xffff800000000000
+o	start of the kernel mapping =  0x0000010000000000
+o	global RAM per system 508*512GB=254 Terabytes
+o	no need of any common code change
+o       512GB of vmalloc/ioremap space
+
+Description:
+        x86-64 has a 4 level page structure, similar to ia32 PSE but with
+        some extensions. Each level consits of a 4K page with 512 64bit
+        entries. The levels are named in Linux PML4, PGD, PMD, PTE; AMD calls them
+        PML4E, PDPE, PDE, PTE respectively. For direct and kernel mapping
+        only 3 levels are used with the PMD pointing to 2MB pages.
+          
+	Userspace is able to modify and it sees only the 3rd/2nd/1st level
+	pagetables (pgd_offset() implicitly walks the 1st slot of the 4th
+	level pagetable and it returns an entry into the 3rd level pagetable).
+	This is where the per-process 512 Gigabytes limit cames from.
+
+	The common code pgd is the PDPE, the pmd is the PDE, the
+	pte is the PTE. The PML4 remains invisible to the common
+	code.
+
+	Since the per-process limit is 512 Gigabytes (due to kernel common
+	code 3 level pagetable limitation), the higher virtual address mapped
+	into userspace is 0x7fffffffff and it makes sense to use it
+	as the top of the userspace stack to allow the stack to grow as
+	much as possible.
+
+	The kernel mapping and the direct memory mapping are split. Direct memory
+	mapping starts directly after userspace after a 512GB gap, while 
+	kernel mapping is at the end of (negative) virtual address space to exploit 
+	the kernel code model. There is no support for discontig memory, this
+	implies that kernel mapping/vmalloc/ioremap/module mapping are not 
+	represented in their "real" mapping in mem_map, but only with their
+	direct mapped (but normally not used) alias.
+	
+Future:
+
+	During 2.5.x we can break the 512 Gigabytes per-process limit
+	possibly by removing from the common code any knowledge about the
+	architectural dependent physical layout of the virtual to physical
+	mapping.
+
+	Once the 512 Gigabytes limit will be removed the kernel stack will
+	be moved (most probably to virtual address 0x00007fffffffffff).
+	Nothing	will break in userspace due that move, as nothing breaks
+	in IA32 compiling the kernel with CONFIG_2G.
+
+Linus agreed on not breaking common code and to live with the 512 Gigabytes
+per-process limitation for the 2.4.x timeframe and he has given me and Andi
+some very useful hints... (thanks! :)
+
+Thanks also to H. Peter Anvin for his interesting and useful suggestions on
+the x86-64-discuss lists!
+
+Current PML4 Layout:
+	Each CPU has an PML4 page that never changes. 
+	Each slot is 512GB of virtual memory. 
+ 
+        0    user space pgd or 40MB low mapping at bootup.  Changed at context switch.
+        1    unmapped
+        2    __PAGE_OFFSET - start of direct mapping of physical memory
+        ...  direct mapping in further slots as needed.
+        510  vmalloc and ioremap space
+	511  kernel code mapping, fixmaps and modules.  
+
+Other memory management related issues follows:
+
+PAGE_SIZE:
+
+	If somebody is wondering why these days we still have a so small
+	4k pagesize (16 or 32 kbytes would be much better for performance
+	of course), the PAGE_SIZE have to remain 4k for 32bit apps to
+	provide 100% backwards compatible IA32 API (we can't allow silent
+	fs corruption or as best a loss of coherency with the page cache
+	by allocating MAP_SHARED areas in MAP_ANONYMOUS memory with a
+	do_mmap_fake). I think it could be possible to have a dynamic page
+	size between 32bit and 64bit apps but it would need extremely
+	intrusive changes in the common code as first for page cache and
+	we sure don't want to depend on them right now even if the
+	hardware would support that.
+
+PAGETABLE SIZE:
+
+	In turn we can't afford to have pagetables larger than 4k because
+	we could not be able to allocate them due physical memory
+	fragmentation, and failing to allocate the kernel stack is a minor
+	issue compared to failing the allocation of a pagetable. If we
+	fail the allocation of a pagetable the only thing we can do is to
+	sched_yield polling the freelist (deadlock prone) or to segfault
+	the task (not even the sighandler would be sure to run).
+
+KERNEL STACK:
+
+	1st stage:
+
+	The kernel stack will be at first allocated with an order 2 allocation
+	(16k) (the utilization of the stack for a 64bit platform really
+	isn't exactly the double of a 32bit platform because the local
+	variables may not be all 64bit wide, but not much less). This will
+	make things even worse than they are right now on IA32 with
+	respect of failing fork/clone due memory fragmentation.
+
+	2nd stage:
+
+	We'll benchmark if reserving one register as task_struct
+	pointer will improve performance of the kernel (instead of
+	recalculating the task_struct pointer starting from the stack
+	pointer each time). My guess is that recalculating will be faster
+	but it worth a try.
+
+		If reserving one register for the task_struct pointer
+		will be faster we can as well split task_struct and kernel
+		stack. task_struct can be a slab allocation or a
+		PAGE_SIZEd allocation, and the kernel stack can then be
+		allocated in a order 1 allocation. Really this is risky,
+		since 8k on a 64bit platform is going to be less than 7k
+		on a 32bit platform but we could try it out. This would
+		reduce the fragmentation problem of an order of magnitude
+		making it equal to the current IA32.
+
+		We must also consider the x86-64 seems to provide in hardware a
+		per-irq stack that could allow us to remove the irq handler
+		footprint from the regular per-process-stack, so it could allow
+		us to live with a smaller kernel stack compared to the other
+		linux architectures.
+
+	3rd stage:
+
+	Before going into production if we still have the order 2
+	allocation we can add a sysctl that allows the kernel stack to be
+	allocated with vmalloc during memory fragmentation. This have to
+	remain turned off during benchmarks :) but it should be ok in real
+	life.
+
+Order of PAGE_CACHE_SIZE and other allocations:
+
+	On the long run we can increase the PAGE_CACHE_SIZE to be
+	an order 2 allocations and also the slab/buffercache etc.ec..
+	could be all done with order 2 allocations. To make the above
+	to work we should change lots of common code thus it can be done
+	only once the basic port will be in a production state. Having
+	a working PAGE_CACHE_SIZE would be a benefit also for
+	IA32 and other architectures of course.
+
+vmalloc:
+	vmalloc should be outside the first 512GB to keep that space free
+	for the user space. It needs an own pgd to work on in common code. 
+	It currently gets an own pgd in the 510th slot of the per CPU PML4.
+	
+PML4: 
+        Each CPU as an own PML4 (=top level of the 4 level page hierarchy). On 
+        context switch the first slot is rewritten to the pgd of the new process 
+        and CR3 is flushed.
+    
+Modules: 
+	Modules need to be in the same 4GB range as the core kernel. Otherwise
+	a GOT would be needed. Modules are currently at 0xffffffffa0000000
+        to 0xffffffffafffffff. This is inbetween the kernel text and the 
+        vsyscall/fixmap mappings.
+
+Vsyscalls: 
+        Vsyscalls have a reserved space near the end of user space that is 
+        acessible by user space. This address is part of the ABI and cannot be
+        changed. They have ffffffffff600000 to ffffffffffe00000 (but only 
+        some small space at the beginning is allocated and known to user space 
+        currently). See vsyscall.c for more details. 
+
+Fixmaps: 
+        Fixed mappings set up at boot. Used to access IO APIC and some other hardware. 
+        These are at the end of vsyscall space (ffffffffffe00000) downwards, 
+        but are not accessible by user space of course.
+
+Early mapping:
+        On a 120TB memory system bootmem could use upto 3.5GB
+        of memory for its bootmem bitmap. To avoid having to map 3.5GB by hand
+        for bootmem's purposes the full direct mapping is created before bootmem
+        is initialized. The direct mapping needs some memory for its page tables,
+        these are directly taken from the physical memory after the kernel. To
+        access these pages they need to be mapped, this is done by a temporary 
+        mapping with a few spare static 2MB PMD entries.
+
+Unsolved issues: 
+	 2MB pages for user space - may need to add a highmem zone for that again to 
+	 avoid fragmentation.
+  
+Andrea <andrea@suse.de> SuSE
+Andi Kleen <ak@suse.de> SuSE
+
+$Id$
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/MAINTAINERS linux-bk/MAINTAINERS
--- linux-2.4.19/MAINTAINERS	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/MAINTAINERS	2002-11-22 15:35:23.000000000 +0000
@@ -1,3 +1,4 @@
+	
 	List of maintainers and how to submit kernel changes
 
 Please try to follow the guidelines below.  This will make things
@@ -241,6 +242,12 @@
 W:	http://www.ife.ee.ethz.ch/~sailer/ham/ham.html
 S:	Maintained
 
+BEFS FILE SYSTEM
+P:	Will Dyson
+M:	will@cs.earlham.edu
+W:	http://cs.earlham.edu/~will/software/linux/kernel/BeFS.html
+S:	Maintained
+
 BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
 P:	Kenji Hollis
 M:	kenji@bitgate.com
@@ -266,6 +273,12 @@
 W:	http://bluez.sf.net
 S:	Maintained
 
+BLUETOOTH SUBSYSTEM (PC Card Drivers)
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
 BTTV VIDEO4LINUX DRIVER
 P:	Gerd Knorr
 M:	kraxel@bytesex.org
@@ -529,7 +542,7 @@
 EMU10K1 SOUND DRIVER
 P:	Rui Sousa	
 M:	rui.p.m.sousa@clix.pt	
-L:	emu10k1-devel@opensource.creative.com
+L:	emu10k1-devel@lists.sourceforge.net
 W:	http://opensource.creative.com/
 S:	Maintained
 
@@ -626,8 +639,8 @@
 S:	Maintained
 
 HFS FILESYSTEM
-P:      Adrian Sun
-M:      asun@cobaltnet.com
+P:      Oliver Neukum
+M:      oliver@neukum.org
 L:      linux-kernel@vger.kernel.org
 S:      Maintained
 
@@ -704,8 +717,10 @@
 S:	Maintained
 
 IBM ServeRAID RAID DRIVER
-P:      Keith Mitchell
-M:      ipslinux@us.ibm.com
+P:      Jack Hammer
+M:      ipslinux@adaptec.com
+P:      David Jeffery
+M:      ipslinux@adaptec.com
 W:      http://www.developer.ibm.com/welcome/netfinity/serveraid.html
 S:      Supported 
 
@@ -796,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:
@@ -852,6 +867,13 @@
 W:	http://sources.redhat.com/jffs2/
 S:	Maintained
 
+JFS FILESYSTEM
+P:	Dave Kleikamp
+M:	shaggy@austin.ibm.com
+L:	jfs-discussion@oss.software.ibm.com
+W:	http://oss.software.ibm.com/developerworks/opensource/jfs/
+S:	Supported
+
 JOYSTICK DRIVER
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -1001,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
@@ -1056,20 +1078,17 @@
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
-NETFILTER
+NETFILTER/IPTABLES
 P:	Rusty Russell
-M:	rusty@rustcorp.com.au
 P:	Marc Boucher
-M:	marc@mbsi.ca
 P:	James Morris
-M:	jamesm@intercode.com.au
 P:	Harald Welte
-M:	laforge@gnumonks.org
 P:	Jozsef Kadlecsik
-M:	kadlec@blackhole.kfki.hu
+M:	coreteam@netfilter.org
 W:	http://www.netfilter.org/
 W:	http://www.iptables.org/
-L:	netfilter@lists.samba.org
+L:	netfilter@lists.netfilter.org
+L:	netfilter-devel@lists.netfilter.org
 S:	Supported
 
 NETROM NETWORK LAYER
@@ -1095,14 +1114,11 @@
 P:	Networking Team
 M:	netdev@oss.sgi.com
 L:	linux-net@vger.kernel.org
-W:	http://www.uk.linux.org/NetNews.html (2.0 only)
 S:	Maintained
 
 NETWORKING [IPv4/IPv6]
 P:	David S. Miller
 M:	davem@redhat.com
-P:	Andi Kleen
-M:	ak@muc.de
 P:	Alexey Kuznetsov
 M:	kuznet@ms2.inr.ac.ru
 P:	Pekka Savola (ipv6)
@@ -1236,7 +1252,7 @@
 
 PCMCIA SUBSYSTEM
 P:	David Hinds
-M:	dhinds@zen.stanford.edu
+M:	dahinds@users.sourceforge.net
 L:	linux-kernel@vger.kernel.org
 W:	http://pcmcia-cs.sourceforge.net
 S:	Maintained
@@ -1257,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
 
@@ -1269,6 +1285,15 @@
 W:	http://www-jcr.lmh.ox.ac.uk/~pnp/
 S:	Maintained
 
+POWERVR2 FRAMEBUFFER DRIVER
+P:	M. R. Brown
+M:	mrbrown@0xd6.org
+P:	Paul Mundt
+M:	lethal@0xd6.org
+L:	linux-fbdev-devel@lists.sourceforge.net
+W:	http://www.linuxdc.org
+S:	Maintained
+
 PPP PROTOCOL DRIVERS AND COMPRESSORS
 P:	Paul Mackerras
 M:	paulus@samba.org
@@ -1353,10 +1378,10 @@
 S:	Maintained
 
 RME96XX MULTICHANNEL SOUND DRIVER
-P:      Guenter Geiger
-M:      geiger@epy.co.at  
-L:      linux-kernel@vger.kernel.org
-S:      Maintained
+P:	Guenter Geiger
+M:	geiger@epy.co.at  
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
 
 RTLINUX  REALTIME  LINUX
 P:	Victor Yodaiken
@@ -1530,6 +1555,13 @@
 W:	http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html
 S:	Maintained
 
+SUPERH WATCHDOG
+P:	Paul Mundt
+M:	lethal@0xd6.org
+L:	linuxsh-dev@lists.sourceforge.net
+W:	http://www.linuxsh.org
+S:	Maintained
+
 SVGA HANDLING
 P:	Martin Mares
 M:	mj@ucw.cz
@@ -1541,6 +1573,20 @@
 M:	hch@infradead.org
 S:	Maintained
 
+TI GRAPH LINK USB (SilverLink) CABLE DRIVER
+P:      Romain Lievin
+M:      roms@lpg.ticalc.org
+P:      Julien Blache
+M:      jb@technologeek.org
+S:      Maintained
+
+TIEMAN VOYAGER USB BRAILLE DISPLAY DRIVER
+P:	Stephane Dalton
+M:	sdalton@videotron.ca
+P:	Stéphane Doyon
+M:	s.doyon@videotron.ca
+S:	Maintained
+
 TIEMAN VOYAGER USB BRAILLE DISPLAY DRIVER
 P:	Stephane Dalton
 M:	sdalton@videotron.ca
@@ -1635,7 +1681,7 @@
 
 USB AUERSWALD DRIVER
 P:	Wolfgang Muees
-M:	wmues@nexgo.de
+M:	wolfgang@iksw-muees.de
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
@@ -1856,6 +1902,13 @@
 M:	mingo@redhat.com
 S:	Maintained
 
+X86-64 port
+P:	Andi Kleen
+M:	ak@suse.de
+L:	discuss@x86-64.org
+W:	http://www.x86-64.org
+S:	Maintained
+
 YAM DRIVER FOR AX.25
 P:	Jean-Paul Roubelat
 M:	jpr@f6fbb.org
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/Makefile linux-bk/Makefile
--- linux-2.4.19/Makefile	2002-08-03 00:39:46.000000000 +0000
+++ linux-bk/Makefile	2002-11-22 15:35:24.000000000 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 19
-EXTRAVERSION =
+SUBLEVEL = 20
+EXTRAVERSION = -rc3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -170,7 +170,7 @@
 DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
 DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o
 DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.o
+DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
 DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a
@@ -180,11 +180,13 @@
 DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
 DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
 DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
+DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
 DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
 DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
 DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
 DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
+DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
 DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
@@ -258,7 +260,7 @@
 # 'kbuild_2_4_nostdinc :=' or -I/usr/include for kernel code and you are not UML
 # then your code is broken!  KAO.
 
-kbuild_2_4_nostdinc	:= -nostdinc $(shell $(CC) -print-search-dirs | sed -ne 's/install: \(.*\)/-I \1include/gp')
+kbuild_2_4_nostdinc	:= -nostdinc -iwithprefix include
 export kbuild_2_4_nostdinc
 
 export	CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
@@ -369,7 +371,7 @@
 TAGS: dummy
 	{ find include/asm-${ARCH} -name '*.h' -print ; \
 	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
-	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | etags -
+	find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | grep -v '\.svn' | etags -
 
 # Exuberant ctags works better with -I
 tags: dummy
@@ -487,7 +489,7 @@
 
 dep-files: scripts/mkdep archdep include/linux/version.h
 	scripts/mkdep -- init/*.c > .depend
-	scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
+	scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
 	$(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
 ifdef CONFIG_MODVERSIONS
 	$(MAKE) update-modverfile
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/config.in linux-bk/arch/alpha/config.in
--- linux-2.4.19/arch/alpha/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/alpha/config.in	2002-11-22 15:35:26.000000000 +0000
@@ -250,9 +250,9 @@
 fi
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   bool 'Discontiguous Memory Support' CONFIG_DISCONTIGMEM
+   bool 'Discontiguous Memory Support (EXPERIMENTAL)' CONFIG_DISCONTIGMEM
    if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then
-      bool ' NUMA Support' CONFIG_NUMA
+      bool ' NUMA Support (EXPERIMENTAL)' CONFIG_NUMA
    fi
 fi
 
@@ -360,7 +360,7 @@
 mainmenu_option next_comment
 comment 'Old CD-ROM drivers (not SCSI, not IDE)'
 
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
+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
@@ -423,3 +423,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/pci.c linux-bk/arch/alpha/kernel/pci.c
--- linux-2.4.19/arch/alpha/kernel/pci.c	2001-11-03 01:39:20.000000000 +0000
+++ linux-bk/arch/alpha/kernel/pci.c	2002-11-22 15:35:24.000000000 +0000
@@ -128,7 +128,8 @@
 #define GB			(1024*MB)
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 	struct pci_controller *hose = dev->sysdata;
@@ -168,7 +169,7 @@
 		 */
 
 		/* Align to multiple of size of minimum base.  */
-		alignto = MAX(0x1000, size);
+		alignto = MAX(0x1000, align);
 		start = ALIGN(start, alignto);
 		if (hose->sparse_mem_base && size <= 7 * 16*MB) {
 			if (((start / (16*MB)) & 0x7) == 0) {
@@ -245,25 +246,6 @@
 		/* Root bus */
 		bus->resource[0] = hose->io_space;
 		bus->resource[1] = hose->mem_space;
-	} else {
-		/* This is a bridge. Do not care how it's initialized,
-		   just link its resources to the bus ones */
-		int i;
-
-		for(i=0; i<3; i++) {
-			bus->resource[i] =
-				&dev->resource[PCI_BRIDGE_RESOURCES+i];
-			bus->resource[i]->name = bus->name;
-		}
-		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->flags |= IORESOURCE_MEM;
-		/* For now, propogate hose limits to the bus;
-		   we'll adjust them later. */
-		bus->resource[0]->end = hose->io_space->end;
-		bus->resource[1]->end = hose->mem_space->end;
-		/* Turn off downstream PF memory address range by default */
-		bus->resource[2]->start = 1024*1024;
-		bus->resource[2]->end = bus->resource[2]->start - 1;
 	}
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -348,10 +330,14 @@
 	ranges->io_end -= hose->io_space->start;
 	ranges->mem_start -= hose->mem_space->start;
 	ranges->mem_end -= hose->mem_space->start;
+/* FIXME: On older alphas we could use dense memory space
+	  to access prefetchable resources. */
+	ranges->prefetch_start -= hose->mem_space->start;
+	ranges->prefetch_end -= hose->mem_space->start;
 }
 
 int
-pcibios_enable_device(struct pci_dev *dev)
+pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	/* Nothing to do, since we enable all devices at startup.  */
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/srm_env.c linux-bk/arch/alpha/kernel/srm_env.c
--- linux-2.4.19/arch/alpha/kernel/srm_env.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/alpha/kernel/srm_env.c	2002-11-22 15:35:25.000000000 +0000
@@ -33,6 +33,15 @@
  * Changelog
  * ~~~~~~~~~
  *
+ * Thu, 22 Aug 2002 15:10:43 +0200
+ * 	- Update Config.help entry. I got a number of emails asking
+ * 	  me to tell their senders if they could make use of this
+ * 	  piece of code... So: "SRM is something like BIOS for your
+ * 	  Alpha"
+ * 	- Update code formatting a bit to better conform CodingStyle
+ * 	  rules.
+ * 	- So this is v0.0.5, with no changes (except formatting)
+ * 	
  * Wed, 22 May 2002 00:11:21 +0200
  * 	- Fix typo on comment (SRC -> SRM)
  * 	- Call this "Version 0.0.4"
@@ -59,13 +68,12 @@
 #define BASE_DIR	"srm_environment"	/* Subdir in /proc/		*/
 #define NAMED_DIR	"named_variables"	/* Subdir for known variables	*/
 #define NUMBERED_DIR	"numbered_variables"	/* Subdir for all variables	*/
-#define VERSION		"0.0.4"			/* Module version		*/
+#define VERSION		"0.0.5"			/* Module version		*/
 #define NAME		"srm_env"		/* Module name			*/
 
 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
 MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
 MODULE_LICENSE("GPL");
-EXPORT_NO_SYMBOLS;
 
 typedef struct _srm_env {
 	char			*name;
@@ -98,9 +106,12 @@
 };
 static srm_env_t	srm_numbered_entries[256];
 
+
+
 static int
 srm_env_read(char *page, char **start, off_t off, int count, int *eof,
-		void *data) {
+		void *data)
+{
 	int		nbytes;
 	unsigned long	ret;
 	srm_env_t	*entry;
@@ -112,11 +123,11 @@
 		return -EFAULT;
 	}
 
-	entry	= (srm_env_t *)data;
+	entry	= (srm_env_t *) data;
 	ret	= callback_getenv(entry->id, page, count);
 
 	if((ret >> 61) == 0)
-		nbytes = (int)ret;
+		nbytes = (int) ret;
 	else
 		nbytes = -EFAULT;
 
@@ -125,9 +136,11 @@
 	return nbytes;
 }
 
+
 static int
 srm_env_write(struct file *file, const char *buffer, unsigned long count,
-		void *data) {
+		void *data)
+{
 #define BUFLEN	512
 	int		nbytes;
 	srm_env_t	*entry;
@@ -157,7 +170,7 @@
 		do 
 			ret2 = callback_save_env();
 		while((ret2 >> 61) == 1);
-		nbytes = (int)ret1;
+		nbytes = (int) ret1;
 	} else
 		nbytes = -EFAULT;
 
@@ -166,8 +179,10 @@
 	return nbytes;
 }
 
+
 static void
-srm_env_cleanup(void) {
+srm_env_cleanup(void)
+{
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
@@ -211,8 +226,10 @@
 	return;
 }
 
+
 static int __init
-srm_env_init(void) {
+srm_env_init(void)
+{
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
@@ -221,7 +238,9 @@
 	 */
 	if(!alpha_using_srm) {
 		printk(KERN_INFO "%s: This Alpha system doesn't "
-				"know about SRM...\n", __FUNCTION__);
+				"know about SRM (or you've booted "
+				"SRM->MILO->Linux, which gets "
+				"misdetected)...\n", __FUNCTION__);
 		return -ENODEV;
 	}
 
@@ -275,7 +294,7 @@
 		if(entry->proc_entry == NULL)
 			goto cleanup;
 
-		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->data		= (void *) entry;
 		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
@@ -296,7 +315,7 @@
 			goto cleanup;
 
 		entry->id			= var_num;
-		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->data		= (void *) entry;
 		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
@@ -304,20 +323,26 @@
 
 	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
 			VERSION);
+
 	return 0;
 
 cleanup:
 	srm_env_cleanup();
+
 	return -ENOMEM;
 }
 
+
 static void __exit
-srm_env_exit(void) {
+srm_env_exit(void)
+{
 	srm_env_cleanup();
 	printk(KERN_INFO "%s: unloaded successfully\n", NAME);
+
 	return;
 }
 
+
 module_init(srm_env_init);
 module_exit(srm_env_exit);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/kernel/traps.c linux-bk/arch/alpha/kernel/traps.c
--- linux-2.4.19/arch/alpha/kernel/traps.c	2001-11-20 23:49:31.000000000 +0000
+++ linux-bk/arch/alpha/kernel/traps.c	2002-11-22 15:35:26.000000000 +0000
@@ -167,6 +167,11 @@
 	dik_show_trace(sp);
 }
 
+void dump_stack(void)
+{
+	show_stack(NULL);
+}
+
 void
 die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/lib/ev6-stxncpy.S linux-bk/arch/alpha/lib/ev6-stxncpy.S
--- linux-2.4.19/arch/alpha/lib/ev6-stxncpy.S	2000-12-11 21:46:26.000000000 +0000
+++ linux-bk/arch/alpha/lib/ev6-stxncpy.S	2002-11-22 15:35:26.000000000 +0000
@@ -205,35 +205,30 @@
 
 	cmpbge	zero, t6, t8	# E :
 	beq	a2, $u_eocfin	# U :
-	nop
+	lda	t6, -1		# E :
 	nop
 
 	bne	t8, $u_final	# U :
-	lda	t6, -1		# E : mask out the bits we have
-	mskql	t6, a1, t6	# U :   already seen (stall)
+	mskql	t6, a1, t6	# U : mask out bits already seen
 	stq_u	t0, 0(a0)	# L : store first output word
+	or      t6, t2, t2	# E : (stall)
 
-	or      t6, t2, t2		# E :
-	cmpbge	zero, t2, t8		# E : find nulls in second partial (stall)
-	addq	a0, 8, a0		# E :
-	subq	a2, 1, a2		# E :
-
+	cmpbge	zero, t2, t8	# E : find nulls in second partial
+	addq	a0, 8, a0	# E :
+	subq	a2, 1, a2	# E :
 	bne	t8, $u_late_head_exit	# U :
+
 	/* Finally, we've got all the stupid leading edge cases taken care
 	   of and we can set up to enter the main loop.  */
 	extql	t2, a1, t1	# U : position hi-bits of lo word
+	beq	a2, $u_eoc	# U :
 	ldq_u	t2, 8(a1)	# L : read next high-order source word
 	addq	a1, 8, a1	# E :
 
-	cmpbge	zero, t2, t8	# E : (stall)
-	beq	a2, $u_eoc	# U :
-	nop
-	nop
-
-	bne	t8, $u_eos	# e1    :
-	nop
-	nop
+	extqh	t2, a1, t0	# U : position lo-bits of hi word (stall)
+	cmpbge	zero, t2, t8	# E :
 	nop
+	bne	t8, $u_eos	# U :
 
 	/* Unaligned copy main loop.  In order to avoid reading too much,
 	   the loop is structured to detect zeros in aligned source words.
@@ -243,6 +238,7 @@
 	   to run as fast as possible.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word
 
@@ -250,25 +246,20 @@
 
 	.align 4
 $u_loop:
-	extqh	t2, a1, t0	# U : extract high bits for current word
-	addq	a1, 8, a1	# E :
-	extql	t2, a1, t3	# U : extract low bits for next time
+	or	t0, t1, t0	# E : current dst word now complete
+	subq	a2, 1, a2	# E : decrement word count
+	extql	t2, a1, t1	# U : extract low bits for next time
 	addq	a0, 8, a0	# E :
 
-	or	t0, t1, t0	# E : current dst word now complete
-	ldq_u	t2, 0(a1)	# U : Latency=3 load high word for next time
-	stq_u	t0, -8(a0)	# U : save the current word (stall)
-	mov	t3, t1		# E :
+	stq_u	t0, -8(a0)	# U : save the current word
+	beq	a2, $u_eoc	# U :
+	ldq_u	t2, 8(a1)	# U : Latency=3 load high word for next time
+	addq	a1, 8, a1	# E :
 
-	subq	a2, 1, a2	# E :
-	cmpbge	zero, t2, t8	# E : test new word for eos (2 cycle stall for data)
-	beq	a2, $u_eoc	# U : (stall)
+	extqh	t2, a1, t0	# U : extract low bits (2 cycle stall)
+	cmpbge	zero, t2, t8	# E : test new word for eos
 	nop
-
 	beq	t8, $u_loop	# U :
-	nop
-	nop
-	nop
 
 	/* We've found a zero somewhere in the source word we just read.
 	   If it resides in the lower half, we have one (probably partial)
@@ -276,11 +267,12 @@
 	   have one full and one partial word left to write out.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word.  */
 $u_eos:
-	extqh	t2, a1, t0	# U :
-	or	t0, t1, t0	# E : first (partial) source word complete (stall)
+	or	t0, t1, t0	# E : first (partial) source word complete
+	nop
 	cmpbge	zero, t0, t8	# E : is the null in this first bit? (stall)
 	bne	t8, $u_final	# U : (stall)
 
@@ -318,17 +310,26 @@
 1:	stq_u	t0, 0(a0)	# L :
 	ret	(t9)		# L0 : Latency=3
 
-$u_eoc:				# end-of-count
-	extqh	t2, a1, t0	# U :
-	or	t0, t1, t0	# E : (stall)
-	cmpbge	zero, t0, t8	# E : (stall)
+	  /* Got to end-of-count before end of string.  
+	     On entry to this basic block:
+	     t1 == the shifted high-order bits from the previous source word  */
+$u_eoc:
+	and	a1, 7, t6	# E : avoid final load if possible
+	sll	t10, t6, t6	# U : (stall)
+	and	t6, 0xff, t6	# E : (stall)
+	bne	t6, 1f		# U : (stall)
+
+	ldq_u	t2, 8(a1)	# L : load final src word
 	nop
+	extqh	t2, a1, t0	# U : extract low bits for last word (stall)
+	or	t1, t0, t1	# E : (stall)
+
+	cmpbge	zero, t1, t8	# E :
+	mov	t1, t0		# E :
 
 $u_eocfin:			# end-of-count, final word
 	or	t10, t8, t8	# E :
 	br	$u_final	# L0 : Latency=3
-	nop
-	nop
 
 	/* Unaligned copy entry point.  */
 	.align 4
@@ -349,9 +350,7 @@
 	mskql	t6, a0, t6	# U :
 	nop
 	nop
-	nop
-1:
-	subq	a1, t4, a1	# E : sub dest misalignment from src addr
+1:	subq	a1, t4, a1	# E : sub dest misalignment from src addr
 
 	/* If source misalignment is larger than dest misalignment, we need
 	   extra startup checks to avoid SEGV.  */
@@ -396,4 +395,3 @@
 	nop
 
 	.end __stxncpy
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/lib/stxncpy.S linux-bk/arch/alpha/lib/stxncpy.S
--- linux-2.4.19/arch/alpha/lib/stxncpy.S	2000-12-11 21:46:26.000000000 +0000
+++ linux-bk/arch/alpha/lib/stxncpy.S	2002-11-22 15:35:34.000000000 +0000
@@ -164,26 +164,29 @@
 	or	t0, t6, t6	# e1    : mask original data for zero test
 	cmpbge	zero, t6, t8	# e0    :
 	beq	a2, $u_eocfin	# .. e1 :
-	bne	t8, $u_final	# e1    :
+	lda	t6, -1		# e0    :
+	bne	t8, $u_final	# .. e1 :
 
-	lda	t6, -1			# e1    : mask out the bits we have
-	mskql	t6, a1, t6		# e0    :   already seen
-	stq_u	t0, 0(a0)		# e0    : store first output word
-	or      t6, t2, t2		# .. e1 :
-	cmpbge	zero, t2, t8		# e0    : find nulls in second partial
-	addq	a0, 8, a0		# .. e1 :
-	subq	a2, 1, a2		# e0    :
+	mskql	t6, a1, t6	# e0    : mask out bits already seen
+	nop			# .. e1 :
+	stq_u	t0, 0(a0)	# e0    : store first output word
+	or      t6, t2, t2	# .. e1 :
+	cmpbge	zero, t2, t8	# e0    : find nulls in second partial
+	addq	a0, 8, a0	# .. e1 :
+	subq	a2, 1, a2	# e0    :
 	bne	t8, $u_late_head_exit	# .. e1 :
 
 	/* Finally, we've got all the stupid leading edge cases taken care
 	   of and we can set up to enter the main loop.  */
 
 	extql	t2, a1, t1	# e0    : position hi-bits of lo word
-	ldq_u	t2, 8(a1)	# .. e1 : read next high-order source word
-	addq	a1, 8, a1	# e0    :
-	cmpbge	zero, t2, t8	# e1 (stall)
-	beq	a2, $u_eoc	# e1    :
-	bne	t8, $u_eos	# e1    :
+	beq	a2, $u_eoc	# .. e1 :
+	ldq_u	t2, 8(a1)	# e0    : read next high-order source word
+	addq	a1, 8, a1	# .. e1 :
+	extqh	t2, a1, t0	# e0    : position lo-bits of hi word (stall)
+	cmpbge	zero, t2, t8	# .. e1 :
+	nop			# e0    :
+	bne	t8, $u_eos	# .. e1 :
 
 	/* Unaligned copy main loop.  In order to avoid reading too much,
 	   the loop is structured to detect zeros in aligned source words.
@@ -193,6 +196,7 @@
 	   to run as fast as possible.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word
 
@@ -200,18 +204,18 @@
 
 	.align 3
 $u_loop:
-	extqh	t2, a1, t0	# e0    : extract high bits for current word
-	addq	a1, 8, a1	# .. e1 :
-	extql	t2, a1, t3	# e0    : extract low bits for next time
-	addq	a0, 8, a0	# .. e1 :
 	or	t0, t1, t0	# e0    : current dst word now complete
-	ldq_u	t2, 0(a1)	# .. e1 : load high word for next time
-	stq_u	t0, -8(a0)	# e0    : save the current word
-	mov	t3, t1		# .. e1 :
-	subq	a2, 1, a2	# e0    :
-	cmpbge	zero, t2, t8	# .. e1 : test new word for eos
-	beq	a2, $u_eoc	# e1    :
-	beq	t8, $u_loop	# e1    :
+	subq	a2, 1, a2	# .. e1 : decrement word count
+	stq_u	t0, 0(a0)	# e0    : save the current word
+	addq	a0, 8, a0	# .. e1 :
+	extql	t2, a1, t1	# e0    : extract high bits for next time
+	beq	a2, $u_eoc	# .. e1 :
+	ldq_u	t2, 8(a1)	# e0    : load high word for next time
+	addq	a1, 8, a1	# .. e1 :
+	nop			# e0    :
+	cmpbge	zero, t2, t8	# e1    : test new word for eos (stall)
+	extqh	t2, a1, t0	# e0    : extract low bits for current word
+	beq	t8, $u_loop	# .. e1 :
 
 	/* We've found a zero somewhere in the source word we just read.
 	   If it resides in the lower half, we have one (probably partial)
@@ -219,12 +223,12 @@
 	   have one full and one partial word left to write out.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word.  */
 $u_eos:
-	extqh	t2, a1, t0	# e0    :
-	or	t0, t1, t0	# e1    : first (partial) source word complete
-
+	or	t0, t1, t0	# e0    : first (partial) source word complete
+	nop			# .. e1 :
 	cmpbge	zero, t0, t8	# e0    : is the null in this first bit?
 	bne	t8, $u_final	# .. e1 (zdb)
 
@@ -260,10 +264,22 @@
 1:	stq_u	t0, 0(a0)	# e0    :
 	ret	(t9)		# .. e1 :
 
-$u_eoc:				# end-of-count
-	extqh	t2, a1, t0
-	or	t0, t1, t0
-	cmpbge	zero, t0, t8
+	/* Got to end-of-count before end of string.  
+	   On entry to this basic block:
+	   t1 == the shifted high-order bits from the previous source word  */
+$u_eoc:
+	and	a1, 7, t6	# e1    :
+	sll	t12, t6, t6	# e0    :
+	and	t6, 0xff, t6	# e0    :
+	bne	t6, 1f		# .. e1 :
+
+	ldq_u	t2, 8(a1)	# e0    : load final src word
+	nop			# .. e1 :
+	extqh	t2, a1, t0	# e0    : extract low bits for last word
+	or	t1, t0, t1	# e1    :
+
+1:	cmpbge	zero, t1, t8
+	mov	t1, t0
 
 $u_eocfin:			# end-of-count, final word
 	or	t10, t8, t8
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/alpha/mm/fault.c linux-bk/arch/alpha/mm/fault.c
--- linux-2.4.19/arch/alpha/mm/fault.c	2001-09-17 23:15:02.000000000 +0000
+++ linux-bk/arch/alpha/mm/fault.c	2002-11-22 15:35:27.000000000 +0000
@@ -88,6 +88,7 @@
 	struct mm_struct *mm = current->mm;
 	unsigned int fixup;
 	int fault;
+	siginfo_t info;
 
 	/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
 	   (or is suppressed by the PALcode).  Support that for older CPUs
@@ -108,6 +109,8 @@
 	if (!mm || in_interrupt())
 		goto no_context;
 
+	info.si_code = SEGV_MAPERR;
+
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 	if (address >= TASK_SIZE)
 		goto vmalloc_fault;
@@ -128,6 +131,7 @@
  * we can handle it..
  */
 good_area:
+	info.si_code = SEGV_ACCERR;
 	if (cause < 0) {
 		if (!(vma->vm_flags & VM_EXEC))
 			goto bad_area;
@@ -147,13 +151,12 @@
 	 * the fault.
 	 */
 	fault = handle_mm_fault(mm, vma, address, cause > 0);
-	up_read(&mm->mmap_sem);
-
 	if (fault < 0)
 		goto out_of_memory;
 	if (fault == 0)
 		goto do_sigbus;
 
+	up_read(&mm->mmap_sem);
 	return;
 
 /*
@@ -164,7 +167,12 @@
 	up_read(&mm->mmap_sem);
 
 	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
+			
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *)address;
+		force_sig_info(SIGSEGV,&info,current);
 		return;
 	}
 
@@ -196,11 +204,10 @@
  */
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk(KERN_ALERT "VM: killing process %s(%d)\n",
 	       current->comm, current->pid);
 	if (!user_mode(regs))
@@ -208,11 +215,17 @@
 	do_exit(SIGKILL);
 
 do_sigbus:
+	up_read(&mm->mmap_sem);
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	force_sig(SIGBUS, current);
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	/* not sure si_code value here  */
+	info.si_code =  BUS_ADRERR;
+	info.si_addr = (void *)address;
+	force_sig_info(SIGBUS,&info,current);
 	if (!user_mode(regs))
 		goto no_context;
 	return;
@@ -220,7 +233,11 @@
 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
 vmalloc_fault:
 	if (user_mode(regs)) {
-		force_sig(SIGSEGV, current);
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *)address;
+		force_sig_info(SIGSEGV,&info,current);
 		return;
 	} else {
 		/* Synchronize this task's top level page-table
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/config.in linux-bk/arch/arm/config.in
--- linux-2.4.19/arch/arm/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/config.in	2002-11-22 15:35:25.000000000 +0000
@@ -417,7 +417,7 @@
 fi
 
 source drivers/pci/Config.in
-bool 'Support hot-pluggable devices' CONFIG_HOTPLUG
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
 if [ "$CONFIG_HOTPLUG" = "y" ]; then
    source drivers/pcmcia/Config.in
 else
@@ -503,7 +503,7 @@
    mainmenu_option next_comment
    comment 'Network device support'
 
-   bool 'Network device support?' CONFIG_NETDEVICES
+   bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
    fi
@@ -530,7 +530,7 @@
 mainmenu_option next_comment
 comment 'SCSI support'
 
-tristate 'SCSI support?' CONFIG_SCSI
+tristate 'SCSI support' CONFIG_SCSI
 
 if [ "$CONFIG_SCSI" != "n" ]; then
    source drivers/scsi/Config.in
@@ -618,7 +618,7 @@
    mainmenu_option next_comment
    comment 'Sound'
 
-   tristate 'Sound support' CONFIG_SOUND
+   tristate 'Sound card support' CONFIG_SOUND
    if [ "$CONFIG_SOUND" != "n" ]; then
       source drivers/sound/Config.in
    fi
@@ -655,3 +655,5 @@
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/kernel/bios32.c linux-bk/arch/arm/kernel/bios32.c
--- linux-2.4.19/arch/arm/kernel/bios32.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/kernel/bios32.c	2002-11-22 15:35:28.000000000 +0000
@@ -354,25 +354,7 @@
 	struct pci_dev *dev = bus->self;
 	int i;
 
-	if (dev) {
-		for (i = 0; i < 3; i++) {
-			if(root->resource[i]) {
-				bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
-				bus->resource[i]->end  = root->resource[i]->end;
-				bus->resource[i]->name = bus->name;
-			}
-		}
-		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->flags |= IORESOURCE_MEM;
-
-		if (root->resource[2])
-			bus->resource[2]->flags = root->resource[2]->flags;
-		else {
-			/* no prefetchable memory region - disable it */
-			bus->resource[2]->start = 1024*1024;
-			bus->resource[2]->end   = bus->resource[2]->start - 1;
-		}
-	} else {
+	if (!dev) {
 		/*
 		 * Assign root bus resources.
 		 */
@@ -587,7 +569,8 @@
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mach-integrator/cpu.c linux-bk/arch/arm/mach-integrator/cpu.c
--- linux-2.4.19/arch/arm/mach-integrator/cpu.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-bk/arch/arm/mach-integrator/cpu.c	2002-11-22 15:35:30.000000000 +0000
@@ -121,7 +121,7 @@
 	cpu_freq_khz = vco_to_freq(vco, 1);
 
 #ifdef CONFIG_CPU_FREQ
-	cpufreq_init(cpu_freq_khz);
+	cpufreq_init(cpu_freq_khz, 1000, 0);
 	cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed);
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mach-sa1100/generic.c linux-bk/arch/arm/mach-sa1100/generic.c
--- linux-2.4.19/arch/arm/mach-sa1100/generic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/mach-sa1100/generic.c	2002-11-22 15:35:26.000000000 +0000
@@ -86,7 +86,7 @@
 
 static int __init sa11x0_init_clock(void)
 {
-	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100);
+	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 0, 0);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/arm/mm/fault-common.c linux-bk/arch/arm/mm/fault-common.c
--- linux-2.4.19/arch/arm/mm/fault-common.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/arm/mm/fault-common.c	2002-11-22 15:35:23.000000000 +0000
@@ -225,8 +225,7 @@
 	 * If we are out of memory for pid1,
 	 * sleep for a while and retry
 	 */
-	tsk->policy |= SCHED_YIELD;
-	schedule();
+	yield();
 	goto survive;
 
 check_stack:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/config.in linux-bk/arch/cris/config.in
--- linux-2.4.19/arch/cris/config.in	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/config.in	2002-11-22 15:35:23.000000000 +0000
@@ -39,6 +39,8 @@
 	bool 'Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
 fi
 
+bool 'Enable ETRAX fast timer API' CONFIG_ETRAX_FAST_TIMER
+
 endmenu
 
 mainmenu_option next_comment
@@ -253,4 +255,6 @@
 if [ "$CONFIG_PROFILE" = "y" ]; then
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
+
+source lib/Config.in
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/Config.in linux-bk/arch/cris/drivers/Config.in
--- linux-2.4.19/arch/cris/drivers/Config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/Config.in	2002-11-22 15:35:25.000000000 +0000
@@ -23,8 +23,7 @@
 
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
-#  bool '  Use fast timers for DMA flush and RS-485 timing' CONFIG_ETRAX_SERIAL_FAST_TIMER n
-  define_bool CONFIG_ETRAX_SERIAL_FAST_TIMER n
+  bool '  Use fast timers for serial DMA flush (experimental)' CONFIG_ETRAX_SERIAL_FAST_TIMER
   if [ "$CONFIG_ETRAX_SERIAL_FAST_TIMER" = "n" ]; then
     bool '  Fast serial port DMA flush' CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
     if [ "$CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST" = "n" ]; then
@@ -156,6 +155,11 @@
 # this is true for most products since PB-I2C seems to be somewhat
 # flawed.. 
 	bool 'I2C uses PB not PB-I2C' CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+
+	if [ "$CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C" = "y" ]; then
+          int '  I2C SDA bit number' CONFIG_ETRAX_I2C_DATA_PORT 0
+          int '  I2C SCL bit number' CONFIG_ETRAX_I2C_CLK_PORT 1
+	fi
 fi
 
 bool 'I2C EEPROM (non-volatile RAM) support' CONFIG_ETRAX_I2C_EEPROM
@@ -182,6 +186,8 @@
 
 fi
 
+bool 'VIRTEX FPGA support' CONFIG_ETRAX_VIRTEX_FPGA
+
 bool 'USB host' CONFIG_ETRAX_USB_HOST
 if [ "$CONFIG_ETRAX_USB_HOST" = "y" ]; then
 	define_bool CONFIG_USB y
@@ -191,7 +197,13 @@
 	define_bool CONFIG_USB n
 fi
 
-bool 'DS1302 Real Time Clock support' CONFIG_ETRAX_DS1302
+bool 'Real Time Clock support' CONFIG_ETRAX_RTC
+if [ "$CONFIG_ETRAX_RTC" = "y" ]; then
+  choice '  RTC chip' \
+    "DS1302 CONFIG_ETRAX_DS1302 \
+     PCF8563  CONFIG_ETRAX_PCF8563" DS1302
+fi
+
 if [ "$CONFIG_ETRAX_DS1302" = "y" ]; then
   bool '  DS1302 RST on Generic Port' CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
   int '  DS1302 RST bit number' CONFIG_ETRAX_DS1302_RSTBIT 2
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/Makefile linux-bk/arch/cris/drivers/Makefile
--- linux-2.4.19/arch/cris/drivers/Makefile	2001-07-04 18:50:38.000000000 +0000
+++ linux-bk/arch/cris/drivers/Makefile	2002-11-22 15:35:22.000000000 +0000
@@ -6,7 +6,7 @@
 
 obj-y :=
 
-
+obj-$(CONFIG_ETRAX_VIRTEX_FPGA)         += virtex.o
 obj-$(CONFIG_ETRAX_ETHERNET)            += ethernet.o
 obj-$(CONFIG_ETRAX_SERIAL)              += serial.o
 obj-$(CONFIG_ETRAX_IDE)                 += ide.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/ds1302.c linux-bk/arch/cris/drivers/ds1302.c
--- linux-2.4.19/arch/cris/drivers/ds1302.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/ds1302.c	2002-11-22 15:35:33.000000000 +0000
@@ -7,6 +7,9 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.13  2002/05/29 15:16:08  johana
+*! Removed unused variables.
+*!
 *! Revision 1.12  2002/04/10 15:35:25  johana
 *! Moved probe function closer to init function and marked it __init.
 *!
@@ -85,7 +88,7 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.12 2002/04/10 15:35:25 johana Exp $
+*! $Id: ds1302.c,v 1.13 2002/05/29 15:16:08 johana Exp $
 *!
 *!***************************************************************************/
 
@@ -322,7 +325,6 @@
 		{
 			struct rtc_time rtc_tm;
 			unsigned char mon, day, hrs, min, sec, leap_yr;
-			unsigned char save_control, save_freq_select;
 			unsigned int yrs;
 
 			if (!capable(CAP_SYS_TIME))
@@ -386,7 +388,6 @@
 		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
 		{
 			int tcs_val;                        
-			unsigned char save_control, save_freq_select;
 
 			if (!capable(CAP_SYS_TIME))
 				return -EPERM;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/gpio.c linux-bk/arch/cris/drivers/gpio.c
--- linux-2.4.19/arch/cris/drivers/gpio.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/gpio.c	2002-11-22 15:35:22.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.15 2002/05/06 13:19:13 johana Exp $
+/* $Id: gpio.c,v 1.17 2002/06/17 15:53:01 johana Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,18 @@
  *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.17  2002/06/17 15:53:01  johana
+ * Added IO_READ_INBITS, IO_READ_OUTBITS, IO_SETGET_INPUT and IO_SETGET_OUTPUT
+ * that take a pointer as argument and thus can handle 32 bit ports (G)
+ * correctly.
+ * These should be used instead of IO_READBITS, IO_SETINPUT and IO_SETOUTPUT.
+ * (especially if Port G bit 31 is used)
+ *
+ * Revision 1.16  2002/06/17 09:59:51  johana
+ * Returning 32 bit values in the ioctl return value doesn't work if bit
+ * 31 is set (could happen for port G), so mask it of with 0x7FFFFFFF.
+ * A new set of ioctl's will be added.
+ *
  * Revision 1.15  2002/05/06 13:19:13  johana
  * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
  *
@@ -330,6 +342,107 @@
  * set alarms to wait for using a subsequent select().
  */
 
+unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
+{
+	/* Set direction 0=unchanged 1=input, 
+	 * return mask with 1=input 
+	 */
+	unsigned long flags;
+	if (USE_PORTS(priv)) {
+		save_flags(flags); cli();
+		*priv->dir = *priv->dir_shadow &= 
+		~((unsigned char)arg & priv->changeable_dir);
+		restore_flags(flags);
+		return ~(*priv->dir_shadow);
+	} else if (priv->minor == GPIO_MINOR_G) {
+		/* We must fiddle with R_GEN_CONFIG to change dir */
+		if (((arg & dir_g_in_bits) != arg) && 
+		    (arg & changeable_dir_g)) {
+			arg &= changeable_dir_g;
+			/* Clear bits in genconfig to set to input */
+			if (arg & (1<<0)) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
+				dir_g_in_bits |= (1<<0);
+				dir_g_out_bits &= ~(1<<0);
+			}
+			if ((arg & 0x0000FF00) == 0x0000FF00) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
+				dir_g_in_bits |= 0x0000FF00;
+				dir_g_out_bits &= ~0x0000FF00;
+			}
+			if ((arg & 0x00FF0000) == 0x00FF0000) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
+				dir_g_in_bits |= 0x00FF0000;
+				dir_g_out_bits &= ~0x00FF0000;
+			}
+			if (arg & (1<<24)) {
+				genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
+				dir_g_in_bits |= (1<<24);
+				dir_g_out_bits &= ~(1<<24);
+			}
+			printk("gpio: SETINPUT on port G set "
+				"genconfig to 0x%08lX "
+				"in_bits: 0x%08lX "
+				"out_bits: 0x%08lX\n", 
+			       (unsigned long)genconfig_shadow, 
+			       dir_g_in_bits, dir_g_out_bits);
+			*R_GEN_CONFIG = genconfig_shadow;
+			/* Must be a >120 ns delay before writing this again */
+				
+		}
+		return dir_g_in_bits;
+	}
+	return 0;
+} /* setget_input */
+
+unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
+{
+	unsigned long flags;
+	if (USE_PORTS(priv)) {
+		save_flags(flags); cli();
+		*priv->dir = *priv->dir_shadow |= 
+		  ((unsigned char)arg & priv->changeable_dir);
+		restore_flags(flags);
+		return *priv->dir_shadow;
+	} else if (priv->minor == GPIO_MINOR_G) {
+		/* We must fiddle with R_GEN_CONFIG to change dir */			
+		if (((arg & dir_g_out_bits) != arg) &&
+		    (arg & changeable_dir_g)) {
+			/* Set bits in genconfig to set to output */
+			if (arg & (1<<0)) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
+				dir_g_out_bits |= (1<<0);
+				dir_g_in_bits &= ~(1<<0);
+			}
+			if ((arg & 0x0000FF00) == 0x0000FF00) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
+				dir_g_out_bits |= 0x0000FF00;
+				dir_g_in_bits &= ~0x0000FF00;
+			}
+			if ((arg & 0x00FF0000) == 0x00FF0000) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
+				dir_g_out_bits |= 0x00FF0000;
+				dir_g_in_bits &= ~0x00FF0000;
+			}
+			if (arg & (1<<24)) {
+				genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
+				dir_g_out_bits |= (1<<24);
+				dir_g_in_bits &= ~(1<<24);
+			}
+			printk("gpio: SETOUTPUT on port G set "
+				"genconfig to 0x%08lX "
+				"in_bits: 0x%08lX "
+				"out_bits: 0x%08lX\n", 
+			       (unsigned long)genconfig_shadow, 
+			       dir_g_in_bits, dir_g_out_bits);
+			*R_GEN_CONFIG = genconfig_shadow;
+			/* Must be a >120 ns delay before writing this again */
+		}
+		return dir_g_out_bits & 0x7FFFFFFF;
+	}
+	return 0;
+} /* setget_output */
+
 static int
 gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
 
@@ -338,18 +451,19 @@
 	   unsigned int cmd, unsigned long arg)
 {
 	unsigned long flags;
+	unsigned long val;
 	struct gpio_private *priv = (struct gpio_private *)file->private_data;
 	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
 		return -EINVAL;
 	}
 
 	switch (_IOC_NR(cmd)) {
-	case IO_READBITS:
+	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
 		// read the port
 		if (USE_PORTS(priv)) {
 			return *priv->port;
 		} else if (priv->minor == GPIO_MINOR_G) {
-			return *R_PORT_G_DATA;
+			return (*R_PORT_G_DATA) & 0x7FFFFFFF;
 		}
 		break;
 	case IO_SETBITS:
@@ -387,113 +501,28 @@
 		priv->highalarm &= ~arg;
 		priv->lowalarm  &= ~arg;
 		break;
-	case IO_READDIR:
+	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
 		/* Read direction 0=input 1=output */
 		if (USE_PORTS(priv)) {
 			return *priv->dir_shadow;
 		} else if (priv->minor == GPIO_MINOR_G) {
 			/* Note: Some bits are both in and out,
-			 * Those that are dual is set hare as well.
+			 * Those that are dual is set here as well.
 			 */
-			return dir_g_shadow | dir_g_out_bits;
+			return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
 		}
-	case IO_SETINPUT:
+	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
 		/* Set direction 0=unchanged 1=input, 
 		 * return mask with 1=input 
 		 */
-		if (USE_PORTS(priv)) {
-			save_flags(flags); cli();
-			*priv->dir = *priv->dir_shadow &= 
-			~((unsigned char)arg & priv->changeable_dir);
-			restore_flags(flags);
-			return ~(*priv->dir_shadow);
-		} else if (priv->minor == GPIO_MINOR_G) {
-			/* We must fiddle with R_GEN_CONFIG to change dir */
-			if (((arg & dir_g_in_bits) != arg) && 
-			    (arg & changeable_dir_g)) {
-				arg &= changeable_dir_g;
-				/* Clear bits in genconfig to set to input */
-				if (arg & (1<<0)) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
-					dir_g_in_bits |= (1<<0);
-					dir_g_out_bits &= ~(1<<0);
-				}
-				if ((arg & 0x0000FF00) == 0x0000FF00) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
-					dir_g_in_bits |= 0x0000FF00;
-					dir_g_out_bits &= ~0x0000FF00;
-				}
-				if ((arg & 0x00FF0000) == 0x00FF0000) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
-					dir_g_in_bits |= 0x00FF0000;
-					dir_g_out_bits &= ~0x00FF0000;
-				}
-				if (arg & (1<<24)) {
-					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
-					dir_g_in_bits |= (1<<24);
-					dir_g_out_bits &= ~(1<<24);
-				}
-				printk("gpio: SETINPUT on port G set "
-					"genconfig to 0x%08lX "
-					"in_bits: 0x%08lX "
-					"out_bits: 0x%08lX\n", 
-				       (unsigned long)genconfig_shadow, 
-				       dir_g_in_bits, dir_g_out_bits);
-				*R_GEN_CONFIG = genconfig_shadow;
-				/* Must be a >120 ns delay before writing this again */
-				
-			}
-			return dir_g_in_bits;
-		}
-		return 0;
-
-	case IO_SETOUTPUT:
+		return setget_input(priv, arg) & 0x7FFFFFFF;
+		break;
+	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
 		/* Set direction 0=unchanged 1=output, 
 		 * return mask with 1=output 
 		 */
-		if (USE_PORTS(priv)) {
-			save_flags(flags); cli();
-			*priv->dir = *priv->dir_shadow |= 
-			  ((unsigned char)arg & priv->changeable_dir);
-			restore_flags(flags);
-			return *priv->dir_shadow;
-		} else if (priv->minor == GPIO_MINOR_G) {
-			/* We must fiddle with R_GEN_CONFIG to change dir */			
-			if (((arg & dir_g_out_bits) != arg) &&
-			    (arg & changeable_dir_g)) {
-				/* Set bits in genconfig to set to output */
-				if (arg & (1<<0)) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
-					dir_g_out_bits |= (1<<0);
-					dir_g_in_bits &= ~(1<<0);
-				}
-				if ((arg & 0x0000FF00) == 0x0000FF00) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
-					dir_g_out_bits |= 0x0000FF00;
-					dir_g_in_bits &= ~0x0000FF00;
-				}
-				if ((arg & 0x00FF0000) == 0x00FF0000) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
-					dir_g_out_bits |= 0x00FF0000;
-					dir_g_in_bits &= ~0x00FF0000;
-				}
-				if (arg & (1<<24)) {
-					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
-					dir_g_out_bits |= (1<<24);
-					dir_g_in_bits &= ~(1<<24);
-				}
-				printk("gpio: SETOUTPUT on port G set "
-					"genconfig to 0x%08lX "
-					"in_bits: 0x%08lX "
-					"out_bits: 0x%08lX\n", 
-				       (unsigned long)genconfig_shadow, 
-				       dir_g_in_bits, dir_g_out_bits);
-				*R_GEN_CONFIG = genconfig_shadow;
-				/* Must be a >120 ns delay before writing this again */
-			}
-			return dir_g_out_bits;
-		}
-		return 0;
+		return setget_output(priv, arg) & 0x7FFFFFFF;
+
 	case IO_SHUTDOWN:
 		SOFT_SHUTDOWN();
 		break;
@@ -521,6 +550,47 @@
 			return -EPERM;
 		}
 		break;
+	case IO_READ_INBITS: 
+		/* *arg is result of reading the input pins */
+		if (USE_PORTS(priv)) {
+			val = *priv->port;
+		} else if (priv->minor == GPIO_MINOR_G) {
+			val = *R_PORT_G_DATA;
+		}
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		return 0;
+		break;
+	case IO_READ_OUTBITS:
+		 /* *arg is result of reading the output shadow */
+		if (USE_PORTS(priv)) {
+			val = *priv->shadow;
+		} else if (priv->minor == GPIO_MINOR_G) {
+			val = port_g_data_shadow;
+		}
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_INPUT: 
+		/* bits set in *arg is set to input,
+		 * *arg updated with current input pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_input(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_OUTPUT:
+		/* bits set in *arg is set to output,
+		 * *arg updated with current output pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_output(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
 	default:
 		if (priv->minor == GPIO_MINOR_LEDS)
 			return gpio_leds_ioctl(cmd, arg);
@@ -690,7 +760,7 @@
 
 #endif
 	gpio_init_port_g();
-	printk("ETRAX 100LX GPIO driver v2.3, (c) 2001, 2002 Axis Communications AB\n");
+	printk("ETRAX 100LX GPIO driver v2.4, (c) 2001, 2002 Axis Communications AB\n");
 
 	return res;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/i2c.c linux-bk/arch/cris/drivers/i2c.c
--- linux-2.4.19/arch/cris/drivers/i2c.c	2001-05-20 00:43:05.000000000 +0000
+++ linux-bk/arch/cris/drivers/i2c.c	2002-11-22 15:35:23.000000000 +0000
@@ -12,6 +12,10 @@
 *!                                 don't use PB_I2C if DS1302 uses same bits,
 *!                                 use PB.
 *! $Log: i2c.c,v $
+*! Revision 1.8  2002/08/13 06:31:53  starvik
+*! Made SDA and SCL line configurable
+*! Modified i2c_inbyte to work with PCF8563
+*!
 *! Revision 1.7  2001/04/04 13:11:36  markusl
 *! Updated according to review remarks
 *!
@@ -40,10 +44,10 @@
 *!
 *! ---------------------------------------------------------------------------
 *!
-*! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN
+*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.7 2001/04/04 13:11:36 markusl Exp $ */
+/* $Id: i2c.c,v 1.8 2002/08/13 06:31:53 starvik Exp $ */
 /****************** INCLUDE FILES SECTION ***********************************/
 
 #include <linux/module.h>
@@ -93,8 +97,15 @@
 
 #ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
 /* Use PB and not PB_I2C */
-#define SDABIT 0
-#define SCLBIT 1
+#ifndef CONFIG_ETRAX_I2C_DATA_PORT
+#define CONFIG_ETRAX_I2C_DATA_PORT 0
+#endif
+#ifndef CONFIG_ETRAX_I2C_CLK_PORT
+#define CONFIG_ETRAX_I2C_CLK_PORT 1
+#endif
+
+#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT
+#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT
 #define i2c_enable() 
 #define i2c_disable() 
 
@@ -114,7 +125,7 @@
 
 /* read a bit from the i2c interface */
 
-#define i2c_getbit() (*R_PORT_PB_READ & (1 << SDABIT))
+#define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)
 
 #else
 /* enable or disable the i2c interface */
@@ -206,7 +217,7 @@
 i2c_outbyte(unsigned char x)
 {
 	int i;
-	
+
 	i2c_dir_out();
 
 	for (i = 0; i < 8; i++) {
@@ -238,65 +249,44 @@
 {
 	unsigned char aBitByte = 0;
 	int i;
-	int iaa;
 
-	/*
-	 * enable output
-	 */
-	i2c_dir_out();
-	/*
-	 * Release data bus by setting
-	 * data high
-	 */
-	i2c_data(I2C_DATA_HIGH);
-	/*
-	 * enable input
-	 */
+	/* Switch off I2C to get bit */
+	i2c_disable();
 	i2c_dir_in();
-	/*
-	 * Use PORT PB instead of I2C
-	 * for input. (I2C not working)
-	 */
-	i2c_clk(1);
-	i2c_data(1);
-	/*
-	 * get bits
-	 */
-	for (i = 0; i < 8; i++) {
-		i2c_delay(CLOCK_LOW_TIME/2);
-		/*
-		 * low clock period
-		 */
+	i2c_delay(CLOCK_HIGH_TIME/2);
+
+	/* Get bit */
+	aBitByte |= i2c_getbit();
+
+	/* Enable I2C */
+	i2c_enable();
+	i2c_dir_out();
+	i2c_delay(CLOCK_LOW_TIME/2);
+
+	for (i = 1; i < 8; i++) {
+		aBitByte <<= 1;
+		/* Clock pulse */
 		i2c_clk(I2C_CLOCK_HIGH);
-		/*
-		 * switch off I2C
-		 */
-		i2c_data(1);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+
+		/* Switch off I2C to get bit */
 		i2c_disable();
 		i2c_dir_in();
-		/*
-		 * wait before getting bit
-		 */
-		i2c_delay(CLOCK_HIGH_TIME/2);
-		aBitByte = (aBitByte << 1);
-		iaa = i2c_getbit();
-		aBitByte = aBitByte | iaa ;
-		/*
-		 * wait
-		 */
 		i2c_delay(CLOCK_HIGH_TIME/2);
-		/*
-		 * end clock puls
-		 */
+
+		/* Get bit */
+		aBitByte |= i2c_getbit();
+
+		/* Enable I2C */
 		i2c_enable();
 		i2c_dir_out();
-		i2c_clk(I2C_CLOCK_LOW);
-		/*
-		 * low clock period
-		 */
 		i2c_delay(CLOCK_LOW_TIME/2);
 	}
-	i2c_dir_out();
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
 	return aBitByte;
 }
 
@@ -421,7 +411,7 @@
 *#
 *#--------------------------------------------------------------------------*/
 int
-i2c_writereg(unsigned char theSlave, unsigned char theReg,
+i2c_writereg(unsigned char theSlave, unsigned char theReg, 
 	     unsigned char theValue)
 {
 	int error, cntr = 3;
@@ -434,31 +424,12 @@
 		 */
 		save_flags(flags);
 		cli();
-		/*
-		 * generate start condition
-		 */
-		i2c_start();
-		/*
-		 * dummy preamble
-		 */
-		i2c_outbyte(0x01);
-		i2c_data(I2C_DATA_HIGH);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
-		i2c_data(I2C_DATA_LOW);
-		i2c_delay(CLOCK_HIGH_TIME);
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
 
 		i2c_start();
 		/*
 		 * send slave address
 		 */
-		i2c_outbyte(theSlave);
+		i2c_outbyte((theSlave & 0xfe));
 		/*
 		 * wait for ack
 		 */
@@ -493,7 +464,7 @@
 		restore_flags(flags);
 		
 	} while(error && cntr--);
-	
+
 	i2c_delay(CLOCK_LOW_TIME);
 	
 	return -error;
@@ -512,7 +483,7 @@
 	unsigned char b = 0;
 	int error, cntr = 3;
 	unsigned long flags;
-		
+
 	do {
 		error = 0;
 		/*
@@ -524,28 +495,11 @@
 		 * generate start condition
 		 */
 		i2c_start();
-		/*
-		 * dummy preamble
-		 */
-		i2c_outbyte(0x01);
-		i2c_data(I2C_DATA_HIGH);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-		i2c_clk(I2C_CLOCK_HIGH);
-		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
-		i2c_data(I2C_DATA_LOW);
-		i2c_delay(CLOCK_HIGH_TIME);
-		i2c_clk(I2C_CLOCK_LOW);
-		i2c_delay(CLOCK_LOW_TIME);
-    
-		i2c_start();
     
 		/*
 		 * send slave address
 		 */
-		i2c_outbyte(theSlave);
+		i2c_outbyte((theSlave & 0xfe));
 		/*
 		 * wait for ack
 		 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/pcf8563.c linux-bk/arch/cris/drivers/pcf8563.c
--- linux-2.4.19/arch/cris/drivers/pcf8563.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/drivers/pcf8563.c	2002-11-22 15:35:30.000000000 +0000
@@ -0,0 +1,258 @@
+/*
+ * PCF8563 RTC
+ *
+ * From Phillips' datasheet:
+ *
+ * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
+ * consumption. A programmable clock output, interupt output and voltage
+ * low detector are also provided. All address and data are transferred
+ * serially via two-line bidirectional I2C-bus. Maximum bus speed is
+ * 400 kbits/s. The built-in word address register is incremented
+ * automatically after each written or read bute.
+ *
+ * Copyright (c) 2002, Axis Communications AB
+ * All rights reserved.
+ *
+ * Author: Tobias Anderberg <tobiasa@axis.com>.
+ *
+ * $Id: pcf8563.c,v 1.1 2002/08/12 13:46:02 starvik Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/svinto.h>
+#include <asm/rtc.h>
+#include "i2c.h"
+
+#define PCF8563_MAJOR 121		/* Local major number. */
+#define DEVICE_NAME "rtc"		/* Name which is registered in /proc/devices. */
+#define PCF8563_NAME "PCF8563"
+#define DRIVER_VERSION "$Rev$"
+
+/* Two simple wrapper macros, saves a few keystrokes. */
+#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
+#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+	
+static const unsigned char days_in_month[] =
+	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int pcf8563_open(struct inode *, struct file *);
+int pcf8563_release(struct inode *, struct file *);
+
+static struct file_operations pcf8563_fops = {
+	owner: THIS_MODULE,
+	ioctl: pcf8563_ioctl,
+	open: pcf8563_open,
+	release: pcf8563_release,
+};
+
+void
+get_rtc_time(struct rtc_time *tm)
+{
+	unsigned long flags;
+	
+	tm->tm_sec = rtc_read(RTC_SECONDS);
+	tm->tm_min = rtc_read(RTC_MINUTES);
+	tm->tm_hour = rtc_read(RTC_HOURS);
+	tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
+	tm->tm_mon = rtc_read(RTC_MONTH);
+	tm->tm_year = rtc_read(RTC_YEAR);
+
+	if (tm->tm_sec & 0x80)
+		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+
+        tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
+	tm->tm_sec &= 0x7f;
+	tm->tm_min &= 0x7f;
+	tm->tm_hour &= 0x3f;
+	tm->tm_mday &= 0x3f;
+	tm->tm_mon &= 0x1f;
+
+	BCD_TO_BIN(tm->tm_sec);
+	BCD_TO_BIN(tm->tm_min);
+	BCD_TO_BIN(tm->tm_hour);
+	BCD_TO_BIN(tm->tm_mday);
+	BCD_TO_BIN(tm->tm_mon);
+	tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
+}
+
+int __init
+pcf8563_init(void)
+{
+	unsigned char ret;
+        struct rtc_time tm;
+        
+	/*
+	 * First of all we need to reset the chip. This is done by
+	 * clearing control1, control2 and clk freq, clear the 
+	 * Voltage Low bit, and resetting all alarms.
+	 */
+	if (rtc_write(RTC_CONTROL1, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CONTROL2, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
+		goto err;
+
+	/* Clear the VL bit in the seconds register. */
+	ret = rtc_read(RTC_SECONDS);
+	
+	if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
+		goto err;
+		
+	/* Reset the alarms. */
+	if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
+		goto err;
+	
+	if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
+		goto err;
+
+	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
+		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", 
+		       PCF8563_NAME, PCF8563_MAJOR);
+		return -1;
+	}
+
+	printk(KERN_INFO "%s Real-Time Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
+        
+	/* Check for low voltage, and warn about it.. */
+	if (rtc_read(RTC_SECONDS) & 0x80)
+		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+	
+	return 0;
+
+err:
+	printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
+	return -1;
+}
+
+void __exit
+pcf8563_exit(void)
+{
+	if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
+		printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
+	}
+}
+
+/*
+ * ioctl calls for this driver. Why return -ENOTTY upon error? Because
+ * POSIX says so!
+ */
+int
+pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	/* Some sanity checks. */
+	if (_IOC_TYPE(cmd) != PCF8563_MAGIC)
+		return -ENOTTY;
+
+	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
+		return -ENOTTY;
+
+	switch (cmd) {
+		case RTC_RD_TIME:
+			{
+				struct rtc_time tm;
+
+				get_rtc_time(&tm);
+
+				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
+					return -EFAULT;
+				}
+
+				return 0;
+			}
+			break;
+		case RTC_SET_TIME:
+			{
+				int leap;
+				int century;
+				unsigned long flags;
+				struct rtc_time tm;
+
+				if (!capable(CAP_SYS_TIME))
+					return -EPERM;
+
+				if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
+					return -EFAULT;
+
+				/* Convert from struct tm to struct rtc_time. */
+				tm.tm_year += 1900;
+				tm.tm_mon += 1;
+				
+				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
+
+				/* Perform some sanity checks. */
+				if ((tm.tm_year < 1970) ||
+				    (tm.tm_mon > 12) ||
+				    (tm.tm_mday == 0) ||
+				    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
+				    (tm.tm_hour >= 24) ||
+				    (tm.tm_min >= 60) ||
+				    (tm.tm_sec >= 60))
+					return -EINVAL;
+
+				century = (tm.tm_year >= 2000) ? 0x80 : 0;
+				tm.tm_year = tm.tm_year % 100;
+
+				BIN_TO_BCD(tm.tm_year);
+				BIN_TO_BCD(tm.tm_mday);
+				BIN_TO_BCD(tm.tm_hour);
+				BIN_TO_BCD(tm.tm_min);
+				BIN_TO_BCD(tm.tm_sec);
+				tm.tm_mon |= century;
+				
+				rtc_write(RTC_YEAR, tm.tm_year);
+				rtc_write(RTC_MONTH, tm.tm_mon);
+				rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
+				rtc_write(RTC_HOURS, tm.tm_hour);
+				rtc_write(RTC_MINUTES, tm.tm_min);
+				rtc_write(RTC_SECONDS, tm.tm_sec);
+
+				return 0;
+			}
+			break;
+		default:
+				return -ENOTTY;
+	}
+
+	return 0;
+}
+
+int 
+pcf8563_open(struct inode *inode, struct file *filp)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+int
+pcf8563_release(struct inode *inode, struct file *filp)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+EXPORT_NO_SYMBOLS;
+module_init(pcf8563_init);
+module_exit(pcf8563_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/serial.c linux-bk/arch/cris/drivers/serial.c
--- linux-2.4.19/arch/cris/drivers/serial.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/serial.c	2002-11-22 15:35:24.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.32 2002/05/22 13:58:00 johana Exp $
+/* $Id: serial.c,v 1.37 2002/08/13 13:02:37 bjornw Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,24 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.37  2002/08/13 13:02:37  bjornw
+ * Removed some warnings because of unused code
+ *
+ * Revision 1.36  2002/08/08 12:50:01  starvik
+ * Serial interrupt is shared with synchronous serial port driver
+ *
+ * Revision 1.35  2002/06/03 10:40:49  starvik
+ * Increased RS-485 RTS toggle timer to 2 characters
+ *
+ * Revision 1.34  2002/05/28 18:59:36  johana
+ * Whitespace and comment fixing to be more like etrax100ser.c 1.71.
+ *
+ * Revision 1.33  2002/05/28 17:55:43  johana
+ * RS-485 uses FAST_TIMER if enabled, and starts a short (one char time)
+ * timer from tranismit_chars (interrupt context).
+ * The timer toggles RTS in interrupt context when expired giving minimum
+ * latencies.
+ *
  * Revision 1.32  2002/05/22 13:58:00  johana
  * Renamed rs_write() to raw_write() and made it inline.
  * New rs_write() handles RS-485 if configured and enabled
@@ -303,7 +321,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.32 $";
+static char *serial_version = "$Revision: 1.37 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -342,7 +360,16 @@
 #include <linux/serial.h>
 /* while we keep our own stuff (struct e100_serial) in a local .h file */
 #include "serial.h"
+#include <asm/fasttimer.h>
 
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
+#error "Disable SERIAL_FLUSH_DMA_FAST to use SERIAL_FAST_TIMER"
+#endif
+#ifndef CONFIG_ETRAX_FAST_TIMER
+#error "Enable FAST_TIMER to use SERIAL_FAST_TIMER"
+#endif
+#endif
 /*
  * All of the compatibilty code so we can compile serial.c against
  * older kernels is hidden in serial_compat.h
@@ -404,8 +431,10 @@
                     const unsigned char *buf, int count);
 static inline int raw_write(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
+#ifdef CONFIG_ETRAX_RS485
 static int e100_write_rs485(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
+#endif
 static int 
 get_lsr_info(struct e100_serial * info, unsigned int *value);
 
@@ -519,6 +548,9 @@
 static struct tty_struct *serial_table[NR_PORTS]; 
 static struct termios *serial_termios[NR_PORTS];
 static struct termios *serial_termios_locked[NR_PORTS];
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+static struct fast_timer fast_timers[NR_PORTS];
+#endif
 
 #ifdef CONFIG_ETRAX_SERIAL_PROC_ENTRY
 #define PROCSTAT(x) x
@@ -538,7 +570,7 @@
 
 static struct ser_statistics_type ser_stat[NR_PORTS];
 
-#else 
+#else
 
 #define PROCSTAT(x)
 
@@ -546,6 +578,9 @@
 
 /* RS-485 */
 #if defined(CONFIG_ETRAX_RS485)
+#ifdef CONFIG_ETRAX_FAST_TIMER
+static struct fast_timer fast_timers_rs485[NR_PORTS];
+#endif
 #if defined(CONFIG_ETRAX_RS485_ON_PA)
 static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT;
 #endif
@@ -578,7 +613,7 @@
 	volatile unsigned char *port;
 	volatile unsigned char *shadow;
 	volatile unsigned char *dir_shadow;
-	
+
 	unsigned char dtr_bit;
 	unsigned char ri_bit;
 	unsigned char dsr_bit;
@@ -872,11 +907,6 @@
 		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
 		restore_flags(flags);
 	}
-#if 0
-	REG_SHADOW_SET(e100_modem_pins[info->line].port,
-		       *e100_modem_pins[info->line].shadow,
-		       e100_modem_pins[info->line].ri_bit, !set);
-#endif
 #endif
 }
 static inline void 
@@ -895,11 +925,6 @@
 		*e100_modem_pins[info->line].port = *e100_modem_pins[info->line].shadow;
 		restore_flags(flags);
 	}
-#if 0
-	REG_SHADOW_SET(e100_modem_pins[info->line].port,
-		       *e100_modem_pins[info->line].shadow,
-		       e100_modem_pins[info->line].cd_bit, !set);
-#endif
 #endif
 }
 
@@ -1014,7 +1039,7 @@
 }
 
 static int
-e100_write_rs485(struct tty_struct *tty, int from_user, 
+e100_write_rs485(struct tty_struct *tty, int from_user,
                  const unsigned char *buf, int count)
 {
 	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
@@ -1031,7 +1056,22 @@
 	info->rs485.enabled = old_enabled;
 	return count;
 }
+
+#ifdef CONFIG_ETRAX_FAST_TIMER
+/* Timer function to toggle RTS when using FAST_TIMER */
+static void rs485_toggle_rts_timer_function(unsigned long data)
+{
+	struct e100_serial *info = (struct e100_serial *)data;
+
+	fast_timers_rs485[info->line].function = NULL;
+	e100_rts(info, info->rs485.rts_after_sent);
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
+	e100_enable_rx(info);
+	e100_enable_rxdma_irq(info);
+#endif
+}
 #endif
+#endif /* CONFIG_ETRAX_RS485 */
 
 /*
  * ------------------------------------------------------------
@@ -1174,6 +1214,16 @@
 		/* our job here is done, don't schedule any new DMA transfer */
 		info->tr_running = 0;
 
+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
+		if (info->rs485.enabled) {
+			/* Set a short timer to toggle RTS */
+			start_one_shot_timer(&fast_timers_rs485[info->line],
+			                     rs485_toggle_rts_timer_function,
+			                     (unsigned long)info,
+			                     info->char_time_usec*2,
+			                     "RS-485");
+		}
+#endif /* RS485 */
 		return;
 	}
 
@@ -1189,7 +1239,7 @@
 	*info->ocmdadr = 1;       /* dma command start -> R_DMAx_CMD */
 	
 	/* DMA is now running (hopefully) */
-}
+} /* transmit_chars */
 
 static void 
 start_transmit(struct e100_serial *info)
@@ -1205,7 +1255,7 @@
 	info->tr_running = 1;
 
 	transmit_chars(info);
-}
+} /* start_transmit */
 
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
 static int serial_fast_timer_started = 0;
@@ -1461,7 +1511,7 @@
 #endif
 
 	/* reset the input dma channel to be sure it works */
-	
+
 	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 	while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
 	       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
@@ -1636,7 +1686,7 @@
 	cli();
 
 	length = tty->flip.count;
-	
+
 	while ((buffer = info->first_recv_buffer) && length < TTY_FLIPBUF_SIZE) {
 		unsigned int count = buffer->length;
 
@@ -1889,7 +1939,7 @@
 			}
 			info->break_detected_cnt = 0;
 			DEBUG_LOG(info->line, "#iERR s d %04X\n",
-				  ((rstat & SER_ERROR_MASK) << 8) | data);
+			          ((rstat & SER_ERROR_MASK) << 8) | data);
 		}
 		PROCSTAT(ser_stat[info->line].early_errors_cnt++);
 	} else { /* It was a valid byte, now let the DMA do the rest */
@@ -1903,8 +1953,8 @@
 			 * previous interrupt we should discard it.
 			 */
 			long elapsed_usec = 
-				(curr_time - info->last_rx_active) * (1000000/HZ) + 
-				curr_time_u - info->last_rx_active_usec;
+			  (curr_time - info->last_rx_active) * (1000000/HZ) + 
+			  curr_time_u - info->last_rx_active_usec;
 			if (elapsed_usec < 2*info->char_time_usec) {
 				DEBUG_LOG(info->line, "FBRK %i\n", info->line);
 				/* Report as BREAK (error) and let
@@ -1942,7 +1992,7 @@
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
 
-		if (!info->uses_dma) 
+		if (!info->enabled || !info->uses_dma) 
 			continue; 
 
 		/* Which line caused the irq? */
@@ -1992,28 +2042,6 @@
 	}
 }
 
-/*
- * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occurred.  The path of
- * hangup processing is:
- *
- * 	serial interrupt routine -> (scheduler tqueue) ->
- * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
- * 
- */
-static void 
-do_serial_hangup(void *private_)
-{
-	struct e100_serial	*info = (struct e100_serial *) private_;
-	struct tty_struct	*tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-	
-	tty_hangup(tty);
-}
-
 static int 
 startup(struct e100_serial * info)
 {
@@ -2025,7 +2053,8 @@
 	if (!xmit_page)
 		return -ENOMEM;
 
-	save_flags(flags); cli();
+	save_flags(flags); 
+	cli();
 
 	/* if it was already initialized, skip this */
 
@@ -2322,7 +2351,7 @@
 
 static inline int 
 raw_write(struct tty_struct * tty, int from_user,
-	 const unsigned char *buf, int count)
+	  const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
@@ -2435,6 +2464,11 @@
 		/* If we are in RS-485 mode, we need to toggle RTS and disable
 		 * the receiver before initiating a DMA transfer
 		 */
+#ifdef CONFIG_ETRAX_FAST_TIMER
+		/* Abort any started timer */
+		fast_timers_rs485[info->line].function = NULL;
+		del_fast_timer(&fast_timers_rs485[info->line]);
+#endif
 		e100_rts(info, info->rs485.rts_on_send);
 #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 		e100_disable_rx(info);
@@ -2482,7 +2516,7 @@
 #endif /* CONFIG_ETRAX_RS485 */
 
 	return count;
-}
+} /* rs_write */
 
 
 /* how much space is available in the xmit buffer? */
@@ -2563,16 +2597,16 @@
 	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 (I_IXOFF(tty))
 		info->x_char = STOP_CHAR(tty);
-	
+
 	/* Turn off RTS line (do this atomic) should here be an else ?? */
-	
+
 	save_flags(flags); 
 	cli();
 	e100_rts(info, 0);
@@ -2586,20 +2620,20 @@
 	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 (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
 		else
 			info->x_char = START_CHAR(tty);
 	}
-	
+
 	/* Assert RTS line (do this atomic) */
-	
+
 	save_flags(flags); 
 	cli();
 	e100_rts(info, 1);
@@ -2722,8 +2756,8 @@
 #ifdef SERIAL_DEBUG_IO 
 struct state_str
 {
-  int state;
-  const char *str;
+	int state;
+	const char *str;
 };
 
 const struct state_str control_state_str[] = {
@@ -3678,6 +3712,15 @@
 			       serial_driver.name, info->line, (unsigned int)info->port);
 		}
 	}
+#ifdef CONFIG_ETRAX_FAST_TIMER
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+	memset(fast_timers, 0, sizeof(fast_timers));
+#endif
+#ifdef CONFIG_ETRAX_RS485
+	memset(fast_timers_rs485, 0, sizeof(fast_timers_rs485));
+#endif
+	fast_timer_init();
+#endif
 
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
@@ -3689,7 +3732,7 @@
 		panic("irq23");
 #endif
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
-	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
+	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
 #endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/sync_serial.c linux-bk/arch/cris/drivers/sync_serial.c
--- linux-2.4.19/arch/cris/drivers/sync_serial.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/drivers/sync_serial.c	2002-11-22 15:35:24.000000000 +0000
@@ -227,7 +227,7 @@
 #else
 	ports[0].use_dma = 0;
 	initialize_port(0);
-	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[0]))
+	if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[0]))
 		panic("Can't allocate sync serial manual irq");
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);	 
 #endif
@@ -258,9 +258,9 @@
 #else
 	ports[1].use_dma = 0;	
 	initialize_port(1);
-	if (port[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
+	if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
 	{
-		if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[1]))
+		if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1]))
 			panic("Can't allocate sync serial manual irq");
 	}
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser3_data, set);	 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/usb-host.c linux-bk/arch/cris/drivers/usb-host.c
--- linux-2.4.19/arch/cris/drivers/usb-host.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/drivers/usb-host.c	2002-11-22 15:35:27.000000000 +0000
@@ -193,17 +193,17 @@
 static USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
 static USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
 
-static urb_t *URB_List[NBR_OF_EP_DESC];
+static struct urb *URB_List[NBR_OF_EP_DESC];
 static kmem_cache_t *usb_desc_cache;
 static struct usb_bus *etrax_usb_bus;
 
 #ifdef USB_DEBUG_DESC
-static void dump_urb (purb_t purb);
+static void dump_urb (struct urb *urb);
 #endif
 static void init_rx_buffers(void);
-static int etrax_rh_unlink_urb (urb_t *urb);
-static void etrax_rh_send_irq(urb_t *urb);
-static void etrax_rh_init_int_timer(urb_t *urb);
+static int etrax_rh_unlink_urb (struct urb *urb);
+static void etrax_rh_send_irq(struct urb *urb);
+static void etrax_rh_init_int_timer(struct urb *urb);
 static void etrax_rh_int_timer_do(unsigned long ptr);
 
 static void etrax_usb_setup_epid(int epid, char devnum, char endpoint,
@@ -214,13 +214,13 @@
 static void etrax_usb_free_epid(int epid);
 static void cleanup_sb(USB_SB_Desc_t *sb);
 
-static void etrax_usb_do_ctrl_hw_add(urb_t *urb, int epid, char maxlen);
-static void etrax_usb_do_bulk_hw_add(urb_t *urb, int epid, char maxlen);
+static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen);
+static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen);
 
-static int etrax_usb_submit_ctrl_urb(urb_t *urb);
+static int etrax_usb_submit_ctrl_urb(struct urb *urb);
 
-static int etrax_usb_submit_urb(urb_t *urb);
-static int etrax_usb_unlink_urb(urb_t *urb);
+static int etrax_usb_submit_urb(struct urb *urb);
+static int etrax_usb_unlink_urb(struct urb *urb);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
 static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
@@ -229,7 +229,7 @@
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
 static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs);
 
-static int etrax_rh_submit_urb (urb_t *urb);
+static int etrax_rh_submit_urb (struct urb *urb);
 
 static int etrax_usb_hc_init(void);
 static void etrax_usb_hc_cleanup(void);
@@ -244,24 +244,24 @@
 };
 
 #ifdef USB_DEBUG_DESC
-static void dump_urb(purb_t purb)
+static void dump_urb(struct urb *urb)
 {
-	printk("\nurb                   :0x%08X\n", purb);
-	printk("next                  :0x%08X\n", purb->next);
-	printk("dev                   :0x%08X\n", purb->dev);
-	printk("pipe                  :0x%08X\n", purb->pipe);
-	printk("status                :%d\n", purb->status);
-	printk("transfer_flags        :0x%08X\n", purb->transfer_flags);
-	printk("transfer_buffer       :0x%08X\n", purb->transfer_buffer);
-	printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk("actual_length         :%d\n", purb->actual_length);
-	printk("setup_packet          :0x%08X\n", purb->setup_packet);
-	printk("start_frame           :%d\n", purb->start_frame);
-	printk("number_of_packets     :%d\n", purb->number_of_packets);
-	printk("interval              :%d\n", purb->interval);
-	printk("error_count           :%d\n", purb->error_count);
-	printk("context               :0x%08X\n", purb->context);
-	printk("complete              :0x%08X\n\n", purb->complete);
+	printk("\nurb                   :0x%08X\n", urb);
+	printk("next                  :0x%08X\n", urb->next);
+	printk("dev                   :0x%08X\n", urb->dev);
+	printk("pipe                  :0x%08X\n", urb->pipe);
+	printk("status                :%d\n", urb->status);
+	printk("transfer_flags        :0x%08X\n", urb->transfer_flags);
+	printk("transfer_buffer       :0x%08X\n", urb->transfer_buffer);
+	printk("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
+	printk("actual_length         :%d\n", urb->actual_length);
+	printk("setup_packet          :0x%08X\n", urb->setup_packet);
+	printk("start_frame           :%d\n", urb->start_frame);
+	printk("number_of_packets     :%d\n", urb->number_of_packets);
+	printk("interval              :%d\n", urb->interval);
+	printk("error_count           :%d\n", urb->error_count);
+	printk("context               :0x%08X\n", urb->context);
+	printk("complete              :0x%08X\n\n", urb->complete);
 }
 
 static void dump_in_desc(USB_IN_Desc_t *in)
@@ -425,7 +425,7 @@
 }
 
 
-static int etrax_usb_unlink_intr_urb(urb_t *urb)
+static int etrax_usb_unlink_intr_urb(struct urb *urb)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -511,7 +511,7 @@
 	} while (tmp_ep != first_ep);
 }
 
-static int etrax_usb_submit_intr_urb(urb_t *urb)
+static int etrax_usb_submit_intr_urb(struct urb *urb)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -641,7 +641,7 @@
 
 static void handle_intr_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 
 	DBFENTER;
 
@@ -694,7 +694,7 @@
 	DBFEXIT;
 }
 
-static int etrax_rh_unlink_urb (urb_t *urb)
+static int etrax_rh_unlink_urb (struct urb *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -711,7 +711,7 @@
 	return 0;
 }
 
-static void etrax_rh_send_irq(urb_t *urb)
+static void etrax_rh_send_irq(struct urb *urb)
 {
 	__u16 data = 0;
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
@@ -744,7 +744,7 @@
 /*	DBFEXIT; */
 }
 
-static void etrax_rh_init_int_timer(urb_t *urb)
+static void etrax_rh_init_int_timer(struct urb *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -763,12 +763,12 @@
 
 static void etrax_rh_int_timer_do(unsigned long ptr)
 {
-	urb_t *urb;
+	struct urb *urb;
 	etrax_hc_t *hc;
 	
 /*	DBFENTER; */
 	
-	urb = (urb_t*)ptr;
+	urb = (struct urb*)ptr;
 	hc = urb->dev->bus->hcpriv;
 	
 	if (hc->rh.send) {
@@ -910,7 +910,7 @@
 	return -1;
 }
 
-static int etrax_usb_submit_bulk_urb(urb_t *urb)
+static int etrax_usb_submit_bulk_urb(struct urb *urb)
 {
 	int epid;
 	char devnum;
@@ -919,7 +919,7 @@
 	char out_traffic;
 	char slow;
 
-	urb_t *tmp_urb;
+	struct urb *tmp_urb;
 	
 	unsigned long flags;
 	
@@ -969,7 +969,7 @@
 	return 0;
 }
 
-static void etrax_usb_do_bulk_hw_add(urb_t *urb, int epid, char maxlen)
+static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen)
 {
 	USB_SB_Desc_t *sb_desc_1;
 
@@ -1086,7 +1086,7 @@
 
 static void handle_bulk_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 	etrax_urb_priv_t *hc_priv;
 	unsigned long flags;
 
@@ -1166,7 +1166,7 @@
 
 /* ---------------------------------------------------------------------------- */
 
-static int etrax_usb_submit_ctrl_urb(urb_t *urb)
+static int etrax_usb_submit_ctrl_urb(struct urb *urb)
 {
 	int epid;
 	char devnum;
@@ -1175,7 +1175,7 @@
 	char out_traffic;
 	char slow;
 
-	urb_t *tmp_urb;
+	struct urb *tmp_urb;
 	
 	unsigned long flags;
 	
@@ -1225,7 +1225,7 @@
 	return 0;
 }
 
-static void etrax_usb_do_ctrl_hw_add(urb_t *urb, int epid, char maxlen)
+static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen)
 {
 	USB_SB_Desc_t *sb_desc_1;
 	USB_SB_Desc_t *sb_desc_2;
@@ -1364,7 +1364,7 @@
 	DBFEXIT;
 }
 
-static int etrax_usb_submit_urb(urb_t *urb)
+static int etrax_usb_submit_urb(struct urb *urb)
 {
 	etrax_hc_t *hc;
 	int rval = -EINVAL;
@@ -1411,7 +1411,7 @@
 	return rval;
 }
 
-static int etrax_usb_unlink_urb(urb_t *urb)
+static int etrax_usb_unlink_urb(struct urb *urb)
 {
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
 	int epid;
@@ -1455,8 +1455,8 @@
 	cli();
 	
 	for (epid = 0; epid < 32; epid++) {
-		urb_t *u = URB_List[epid];
-		urb_t *prev = NULL;
+		struct urb *u = URB_List[epid];
+		struct urb *prev = NULL;
 		int pos = 0;
 
 		for (; u; u = u->next) {
@@ -1557,7 +1557,7 @@
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
 {
 	int epid = 0;
-	urb_t *urb;
+	struct urb *urb;
 	etrax_urb_priv_t *urb_priv;
 		
 	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
@@ -1655,7 +1655,7 @@
 
 static void handle_control_transfer_attn(int epid, int status)
 {
-	urb_t *old_urb;
+	struct urb *old_urb;
 	etrax_urb_priv_t *hc_priv;	
 
 	DBFENTER;
@@ -1981,12 +1981,12 @@
 	DBFEXIT;
 }
 
-static int etrax_rh_submit_urb(urb_t *urb)
+static int etrax_rh_submit_urb(struct urb *urb)
 {
 	struct usb_device *usb_dev = urb->dev;
 	etrax_hc_t *hc = usb_dev->bus->hcpriv;
 	unsigned int pipe = urb->pipe;
-	devrequest *cmd = (devrequest *) urb->setup_packet;
+	struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet;
 	void *data = urb->transfer_buffer;
 	int leni = urb->transfer_buffer_length;
 	int len = 0;
@@ -2010,10 +2010,10 @@
 		return 0;
 	}
 
-	bmRType_bReq = cmd->requesttype | cmd->request << 8;
-	wValue = le16_to_cpu(cmd->value);
-	wIndex = le16_to_cpu(cmd->index);
-	wLength = le16_to_cpu(cmd->length);
+	bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8;
+	wValue = le16_to_cpu(cmd->wValue);
+	wIndex = le16_to_cpu(cmd->wIndex);
+	wLength = le16_to_cpu(cmd->wLength);
 
 	dbg_rh("bmRType_bReq : 0x%04X (%d)", bmRType_bReq, bmRType_bReq);
 	dbg_rh("wValue       : 0x%04X (%d)", wValue, wValue);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/virtex.c linux-bk/arch/cris/drivers/virtex.c
--- linux-2.4.19/arch/cris/drivers/virtex.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/drivers/virtex.c	2002-11-22 15:35:22.000000000 +0000
@@ -0,0 +1,405 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : vertex.c
+*!
+*! DESCRIPTION: Implements an interface towards virtex FPGA (mounted on one of our
+*!              evaluation boards) from userspace using ioctl()'s
+*!
+*!              The FPGA can be programmed by copying the bit-file to /dev/fpga.
+*!
+*!                cp fpga.bit > /dev/fpga
+*!
+*!                Kernel log should look like:
+*!                  69900 bytes written
+*!                  FPGA-configuration completed, no errors
+*!
+*!              Number of bytes written depends on the FPGA
+*!
+*!                From Xilinx data sheet:
+*!                XCV50    559,200 bits
+*!                XCV100   781,216 bits
+*!                XCV800 4,715,616 bits
+*!
+*!              Accepted file type is the design.bit generated by Alliance
+*!              Design Manager.
+*!              This software just sends the bitfile into the device without
+*!              checking device type etc.
+*!
+*!              Sync-header 0xff 0xff 0xff 0xff defines the start for the
+*!              byte stream, everything from that position is written to the FPGA.
+*!
+*!  
+*! Jul 19 2002  Stefan Lundberg    Initial version.
+*! $Log: virtex.c,v $
+*! Revision 1.1  2002/06/25 09:58:58  stefanl
+*! New FPGA driver for Platoon
+*!
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN
+*!
+*!***************************************************************************/
+/* $Id: virtex.c,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+/****************** INCLUDE FILES SECTION ***********************************/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/config.h>
+
+#include <linux/hdreg.h>
+#include <linux/mm.h>
+
+#include <asm/etraxvirtex.h>
+
+#include <asm/system.h>
+#include <asm/svinto.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include "virtex.h"
+
+/******************* VIRTEX DEFINITION SECTION **************************/
+
+#define VIRTEX_DEBUG(x)
+
+#define VIRTEX_MAJOR 246  /* EXPERIMENTAL */
+
+static const char virtex_name[] = "virtex";
+
+/****************** FUNCTION DEFINITION SECTION *************************/
+
+
+
+//
+// Read register interface for FPGA programming:
+//
+//   FPGA_DONE is connected to S1CD_N G28
+//   FPGA_INIT_N is connected to S1IO_N G27
+//
+
+// Write register interface for FPGA programming:
+//
+//  Bit:       15         14      13    12      9   8   7   0
+//        ____________________________________________________
+//       | fpga_write | program | cclk | reserved | cs | data |
+//       |____________|_________|______|__________|____|______|
+//
+
+
+// csp0 = cs_fpga1 = FPGA programming interface
+// csr0 = cs_fpga2 = register interface towards FPGA construction
+
+static volatile short *port_csp0_word_addr;
+static volatile short *port_csr0_word_addr;
+
+static volatile unsigned char open_count;
+static volatile unsigned char bytes_written;
+static volatile unsigned long bytes_written_cnt;
+static volatile unsigned char sync_found;
+static volatile unsigned char sync_count;
+static volatile unsigned char sync_ff_count;
+
+#define WRITE_FPGA_PROG_REG(data) *port_csp0_word_addr=(data)
+#define SET_PROGRAM_BIT(data) (data)|(1<<14)
+
+#define SET_WRITE_BIT(data) (data)|(1<<15)
+#define CLR_WRITE_BIT(data) (data)&(~(1<<15))
+
+#define SET_CS_BIT(data) (data)|(1<<8)
+#define CLR_CS_BIT(data) (data)&(~(1<<8))
+
+#define SET_CCLK_BIT(data) (data)|(1<<13)
+#define CLR_CCLK_BIT(data) (data)&(~(1<<13))
+
+// Bit in read port G (always inputs)
+#define READ_INIT  (*R_PORT_G_DATA)&(1<<27)
+#define READ_DONE  (*R_PORT_G_DATA)&(1<<28)
+
+
+void start_virtex_program(void)
+{
+  unsigned short reg_data=0;
+
+  printk("Start writing to FPGA\n");
+  reg_data = SET_CS_BIT(reg_data); // FPGA unselected
+
+  reg_data = SET_PROGRAM_BIT(reg_data);
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  while(!READ_INIT); // Wait for init
+  
+  reg_data = SET_WRITE_BIT(reg_data);
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  reg_data = CLR_CS_BIT(reg_data); // FPGA selected, CS is active low
+  WRITE_FPGA_PROG_REG(reg_data);
+  return;
+}
+
+// According to datasheet, bytes should be reversed, it is unknown to me why.
+unsigned char bit_reverse(unsigned char data) 
+{
+  unsigned char in=data;
+  unsigned short out=0;
+  unsigned int i=0;
+
+  for(i=0;i<8;i++) {
+    if(in&0x1) {
+      out|=0x1;
+    }
+    in=in>>1;
+    out=out<<1;
+  }
+
+  return(out>>1);
+  
+}
+
+void virtex_program(char* ptr,size_t count)
+{
+  int c;
+  char *p;
+  unsigned char data;  
+  unsigned short reg_data=0;
+//  short tmp_cnt;
+  
+  c=count;
+  p=ptr;
+
+  if(!sync_found) {
+    c=count;
+    p=ptr;
+    while(c--) {
+      data=(unsigned char)*p++;
+      sync_count++;
+
+      if(sync_count>=256) {
+        printk("Sync not found, aborting\n");
+        return;
+      }
+
+      if(data==0xff) {
+        sync_ff_count++;
+      } else {
+        sync_ff_count=0;
+      }
+      if(sync_ff_count==4) {
+        sync_found=1;
+        VIRTEX_DEBUG(printk("Sync found at offset %d\n",sync_count));
+        p--;p--;p--;p--;
+        c++;c++;c++;c++;
+        break;
+      }
+    }
+  }
+
+  if(sync_found) {
+    if(bytes_written==0) {
+      start_virtex_program();
+    }
+    bytes_written=1;
+  
+    reg_data = SET_PROGRAM_BIT(reg_data);
+    reg_data = SET_WRITE_BIT(reg_data);
+    reg_data = CLR_CS_BIT(reg_data);
+  
+//    tmp_cnt=0;
+    
+    printk("*");
+    while(c--) {
+      data=(unsigned char)*p++;
+      data=bit_reverse(data);
+
+/* debug
+      tmp_cnt++;
+      if(tmp_cnt<=32 || c<=32 ) {
+        printk("0x%x ",data); 
+      }
+      if(tmp_cnt==32 || c==0 ) {
+        printk("\n"); 
+      }
+*/
+      bytes_written_cnt++;
+      reg_data = CLR_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+      reg_data = SET_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+      reg_data = CLR_CCLK_BIT(reg_data);
+      WRITE_FPGA_PROG_REG(reg_data|(data&0xff));
+  
+    }
+  }
+   
+  return;
+}
+
+void stop_virtex_program(void)
+{
+  unsigned short reg_data=0;
+
+  reg_data = SET_PROGRAM_BIT(reg_data);
+  reg_data = SET_WRITE_BIT(reg_data);
+  reg_data = CLR_CCLK_BIT(reg_data);
+
+  reg_data = SET_CS_BIT(reg_data); // release CS
+  WRITE_FPGA_PROG_REG(reg_data);
+
+  reg_data = CLR_WRITE_BIT(reg_data); // release write, important to do!
+  WRITE_FPGA_PROG_REG(reg_data);
+  printk("%d bytes written\n",bytes_written_cnt);
+  if(READ_DONE) {
+    printk("FPGA-configuration completed, no errors\n");
+  } else {
+    printk("Error, FPGA-configuration failed\n");
+  }
+  return;
+}
+
+static int
+virtex_open(struct inode *inode, struct file *filp)
+{
+  port_csp0_word_addr = port_csp0_addr;
+  if(open_count>=1) {
+    printk("FPGA Device busy, aborting\n");
+    return(-EBUSY);
+  }
+  open_count++;
+  bytes_written=0;
+  sync_found=0;
+  sync_count=0;
+  sync_ff_count=0;
+  bytes_written_cnt=0;
+  return(0);
+}
+
+static int
+virtex_release(struct inode *inode, struct file *filp)
+{
+  open_count--;
+  if(bytes_written!=0)stop_virtex_program();
+  return 0;
+}
+
+// FPGA programming interface
+
+static ssize_t virtex_write(struct file * file, const char * buf, 
+                                 size_t count, loff_t *ppos)
+{
+  char *ptr;
+  VIRTEX_DEBUG(printk("Write FPGA count %d\n", count));
+  
+  ptr=kmalloc(count, GFP_KERNEL);
+  if(!ptr) {
+    printk("FPGA device, kernel malloc failed (%d) bytes\n",count);
+    return -EFAULT;
+  }
+  if(copy_from_user(ptr, buf, count)) {
+    printk("copy_from_user failed\n");
+    return -EFAULT;
+  }
+  
+  virtex_program(ptr,count);
+  
+  kfree(ptr);
+  return count;
+}
+
+/* Main device API. ioctl's to write or read to/from registers.
+ */
+
+int virtex_writereg(unsigned short theReg, unsigned short theValue)
+{
+  port_csr0_word_addr[theReg]=theValue;
+  return(0);
+}
+
+unsigned short virtex_readreg(unsigned short theReg)
+{
+  return(port_csr0_word_addr[theReg]);
+}
+
+
+static int
+virtex_ioctl(struct inode *inode, struct file *file,
+	  unsigned int cmd, unsigned long arg)
+{
+  if(_IOC_TYPE(cmd) != ETRAXVIRTEX_FPGA_IOCTYPE) {
+    return -EINVAL;
+  }
+  
+  switch (_IOC_NR(cmd)) {
+    case VIRTEX_FPGA_WRITEREG:
+      /* write to an FPGA register */
+      VIRTEX_DEBUG(printk("virtex wr %d %d\n", 
+               VIRTEX_FPGA_ARGREG(arg),
+               VIRTEX_FPGA_ARGVALUE(arg)));
+      
+      return virtex_writereg(VIRTEX_FPGA_ARGREG(arg),
+                             VIRTEX_FPGA_ARGVALUE(arg));
+    case VIRTEX_FPGA_READREG:
+    {
+      unsigned char val;
+      /* read from an FPGA register */
+      VIRTEX_DEBUG(printk("virtex rd %d ", 
+              VIRTEX_FPGA_ARGREG(arg)));
+      val = virtex_readreg(VIRTEX_FPGA_ARGREG(arg));
+      VIRTEX_DEBUG(printk("= %d\n", val));
+      return val;
+    }					    
+    default:
+      return -EINVAL;
+    }
+
+return 0;
+}
+
+static struct file_operations virtex_fops = {
+	owner:    THIS_MODULE,
+	ioctl:    virtex_ioctl,
+	open:     virtex_open,
+        write:    virtex_write,
+	release:  virtex_release,
+};
+
+static int __init
+virtex_init(void)
+{
+  int res;
+  
+  /* register char device */
+  res = register_chrdev(VIRTEX_MAJOR, virtex_name, &virtex_fops);
+  if(res < 0) {
+          printk(KERN_ERR "virtex: couldn't get a major number.\n");
+          return res;
+  }
+  
+  port_csr0_word_addr = (volatile unsigned short *) 
+                        ioremap((unsigned long)(MEM_CSR0_START |
+                                                MEM_NON_CACHEABLE), 16);
+     
+// see ~/platoon/rel2/platoon/os/linux/arch/cris/mm/init.c
+//              port_csp0_addr = (volatile unsigned long *)
+//                 ioremap((unsigned long)(MEM_CSP0_START |
+//                                         MEM_NON_CACHEABLE), 16);
+  
+  open_count=0;
+  
+  printk("VIRTEX(TM) FPGA driver v1.0, (c) 2002 Axis Communications AB\n");
+  
+  return 0;
+}
+
+/* this makes sure that virtex_init is called during boot */
+
+module_init(virtex_init);
+
+/****************** END OF FILE virtex.c ********************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/drivers/virtex.h linux-bk/arch/cris/drivers/virtex.h
--- linux-2.4.19/arch/cris/drivers/virtex.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/drivers/virtex.h	2002-11-22 15:35:31.000000000 +0000
@@ -0,0 +1,7 @@
+/* $Id: virtex.h,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+
+int virtex_writereg(unsigned short theReg, unsigned short theValue);
+unsigned short virtex_readreg(unsigned short theReg);
+
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/Makefile linux-bk/arch/cris/kernel/Makefile
--- linux-2.4.19/arch/cris/kernel/Makefile	2001-11-09 21:58:02.000000000 +0000
+++ linux-bk/arch/cris/kernel/Makefile	2002-11-22 15:35:23.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.9 2001/10/22 13:10:21 pkj Exp $
+# $Id: Makefile,v 1.10 2002/05/27 15:41:40 johana Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -25,6 +25,7 @@
 
 obj-$(CONFIG_MODULES)    += ksyms.o
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
+obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
 
 # This dependency isn't caught by mkdep.  See entry.S.
 entry.o: entryoffsets.s
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/fasttimer.c linux-bk/arch/cris/kernel/fasttimer.c
--- linux-2.4.19/arch/cris/kernel/fasttimer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/cris/kernel/fasttimer.c	2002-11-22 15:35:27.000000000 +0000
@@ -0,0 +1,974 @@
+/* $Id: fasttimer.c,v 1.4 2002/05/28 17:47:59 johana Exp $
+ * linux/arch/cris/kernel/fasttimer.c
+ *
+ * Fast timers for ETRAX100/ETRAX100LX
+ * This may be useful in other OS than Linux so use 2 space indentation...
+ *
+ * $Log: fasttimer.c,v $
+ * Revision 1.4  2002/05/28 17:47:59  johana
+ * Added del_fast_timer()
+ *
+ * Revision 1.3  2002/05/28 16:16:07  johana
+ * Handle empty fast_timer_list
+ *
+ * Revision 1.2  2002/05/27 15:38:42  johana
+ * Made it compile without warnings on Linux 2.4.
+ * (includes, wait_queue, PROC_FS and snprintf)
+ *
+ * Revision 1.1  2002/05/27 15:32:25  johana
+ * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
+ *
+ * Revision 1.8  2001/11/27 13:50:40  pkj
+ * Disable interrupts while stopping the timer and while modifying the
+ * list of active timers in timer1_handler() as it may be interrupted
+ * by other interrupts (e.g., the serial interrupt) which may add fast
+ * timers.
+ *
+ * Revision 1.7  2001/11/22 11:50:32  pkj
+ * * Only store information about the last 16 timers.
+ * * proc_fasttimer_read() now uses an allocated buffer, since it
+ *   requires more space than just a page even for only writing the
+ *   last 16 timers. The buffer is only allocated on request, so
+ *   unless /proc/fasttimer is read, it is never allocated.
+ * * Renamed fast_timer_started to fast_timers_started to match
+ *   fast_timers_added and fast_timers_expired.
+ * * Some clean-up.
+ *
+ * Revision 1.6  2000/12/13 14:02:08  johana
+ * Removed volatile for fast_timer_list
+ *
+ * Revision 1.5  2000/12/13 13:55:35  johana
+ * Added DEBUG_LOG, added som cli() and cleanup
+ *
+ * Revision 1.4  2000/12/05 13:48:50  johana
+ * Added range check when writing proc file, modified timer int handling
+ *
+ * Revision 1.3  2000/11/23 10:10:20  johana
+ * More debug/logging possibilities.
+ * Moved GET_JIFFIES_USEC() to timex.h and time.c
+ *
+ * Revision 1.2  2000/11/01 13:41:04  johana
+ * Clean up and bugfixes.
+ * Created new do_gettimeofday_fast() that gets a timeval struct
+ * with time based on jiffies and *R_TIMER0_DATA, uses a table
+ * for fast conversion of timer value to microseconds.
+ * (Much faster the standard do_gettimeofday() and we don't really
+ * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * when we change the time.
+ * TODO: Add efficient support for continuous timers as well.
+ *
+ * Revision 1.1  2000/10/26 15:49:16  johana
+ * Added fasttimer, highresolution timers.
+ *
+ * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/rtc.h>
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <asm/svinto.h>
+#include <asm/fasttimer.h>
+#include <linux/proc_fs.h>
+
+
+#define DEBUG_LOG_INCLUDED
+#define FAST_TIMER_LOG
+//#define FAST_TIMER_TEST
+
+#define FAST_TIMER_SANITY_CHECKS
+
+#ifdef FAST_TIMER_SANITY_CHECKS
+#define SANITYCHECK(x) x
+static int sanity_failed = 0;
+#else
+#define SANITYCHECK(x)
+#endif
+
+#define D1(x)
+#define D2(x)
+#define DP(x)
+
+#define __INLINE__ inline
+
+static int fast_timer_running = 0;
+static int fast_timers_added = 0;
+static int fast_timers_started = 0;
+static int fast_timers_expired = 0;
+static int fast_timers_deleted = 0;
+static int fast_timer_is_init = 0;
+static int fast_timer_ints = 0;
+
+static struct fast_timer *fast_timer_list = NULL;
+
+#ifdef DEBUG_LOG_INCLUDED
+#define DEBUG_LOG_MAX 128
+static const char * debug_log_string[DEBUG_LOG_MAX];
+static unsigned long debug_log_value[DEBUG_LOG_MAX];
+static int debug_log_cnt = 0;
+static int debug_log_cnt_wrapped = 0;
+
+#define DEBUG_LOG(string, value) \
+{ \
+  unsigned long log_flags; \
+  save_flags(log_flags); \
+  cli(); \
+  debug_log_string[debug_log_cnt] = (string); \
+  debug_log_value[debug_log_cnt] = (unsigned long)(value); \
+  if (++debug_log_cnt >= DEBUG_LOG_MAX) \
+  { \
+    debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
+    debug_log_cnt_wrapped = 1; \
+  } \
+  restore_flags(log_flags); \
+}
+#else
+#define DEBUG_LOG(string, value)
+#endif
+
+
+/* The frequencies for index = clkselx number in R_TIMER_CTRL */
+#define NUM_TIMER_FREQ 15
+#define MAX_USABLE_TIMER_FREQ 7
+#define MAX_DELAY_US  853333L
+const unsigned long timer_freq_100[NUM_TIMER_FREQ] =
+{
+  3,   /* 0 3333 - 853333 us */
+  6,   /* 1 1666 - 426666 us */
+  12,  /* 2  833 - 213333 us */
+  24,  /* 3  416 - 106666 us */
+  48,  /* 4  208 -  53333 us */
+  96,  /* 5  104 -  26666 us */
+  192, /* 6   52 -  13333 us */
+  384, /* 7   26 -   6666 us */
+  576,
+  1152,
+  2304,
+  4608,
+  9216,
+  18432,
+  62500,
+  /* 15 = cascade */
+};
+#define NUM_TIMER_STATS 16
+#ifdef FAST_TIMER_LOG
+struct fast_timer timer_added_log[NUM_TIMER_STATS];
+struct fast_timer timer_started_log[NUM_TIMER_STATS];
+struct fast_timer timer_expired_log[NUM_TIMER_STATS];
+#endif
+
+int timer_div_settings[NUM_TIMER_STATS];
+int timer_freq_settings[NUM_TIMER_STATS];
+int timer_delay_settings[NUM_TIMER_STATS];
+
+/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
+void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
+{
+  unsigned long sec = jiffies;
+  unsigned long usec = GET_JIFFIES_USEC();
+
+  usec += (sec % HZ) * (1000000 / HZ);
+  sec = sec / HZ;
+
+  if (usec > 1000000)
+  {
+    usec -= 1000000;
+    sec++;
+  }
+  tv->tv_sec = sec;
+  tv->tv_usec = usec;
+}
+
+int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
+{
+  if (t0->tv_sec < t1->tv_sec)
+  {
+    return -1;
+  }
+  else if (t0->tv_sec > t1->tv_sec)
+  {
+    return 1;
+  }
+  if (t0->tv_usec < t1->tv_usec)
+  {
+    return -1;
+  }
+  else if (t0->tv_usec > t1->tv_usec)
+  {
+    return 1;
+  }
+  return 0;
+}
+
+void __INLINE__ start_timer1(unsigned long delay_us)
+{
+  int freq_index = 0; /* This is the lowest resolution */
+  unsigned long upper_limit = MAX_DELAY_US;
+
+  unsigned long div;
+  /* Start/Restart the timer to the new shorter value */
+  /* t = 1/freq = 1/19200 = 53us
+   * T=div*t,  div = T/t = delay_us*freq/1000000
+   */
+#if 1 /* Adaptive timer settings */
+  while (delay_us < upper_limit && freq_index < MAX_USABLE_TIMER_FREQ)
+  {
+    freq_index++;
+    upper_limit >>= 1; /* Divide by 2 using shift */
+  }
+  if (freq_index > 0)
+  {
+    freq_index--;
+  }
+#else
+  freq_index = 6;
+#endif
+  div = delay_us * timer_freq_100[freq_index]/10000;
+  if (div < 2)
+  {
+    /* Maybe increase timer freq? */
+    div = 2;
+  }
+  if (div > 255)
+  {
+    div = 0; /* This means 256, the max the timer takes */
+    /* If a longer timeout than the timer can handle is used,
+     * then we must restart it when it goes off.
+     */
+  }
+
+  timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = div;
+  timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index;
+  timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
+
+  D1(printk("start_timer1 : %d us freq: %i div: %i\n",
+            delay_us, freq_index, div));
+  /* Clear timer1 irq */
+  *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
+
+  /* Set timer values */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow &
+     ~IO_MASK(R_TIMER_CTRL, timerdiv1) &
+     ~IO_MASK(R_TIMER_CTRL, tm1) &
+     ~IO_MASK(R_TIMER_CTRL, clksel1)) |
+    IO_FIELD(R_TIMER_CTRL, timerdiv1, div) |
+    IO_STATE(R_TIMER_CTRL, tm1, stop_ld) |
+    IO_FIELD(R_TIMER_CTRL, clksel1, freq_index ); /* 6=c19k2Hz */
+
+  /* Ack interrupt */
+  *R_TIMER_CTRL =  r_timer_ctrl_shadow |
+    IO_STATE(R_TIMER_CTRL, i1, clr);
+
+  /* Start timer */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
+    IO_STATE(R_TIMER_CTRL, tm1, run);
+
+  /* Enable timer1 irq */
+  *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer1, set);
+  fast_timers_started++;
+  fast_timer_running = 1;
+}
+
+/* In version 1.4 this function takes 27 - 50 us */
+void start_one_shot_timer(struct fast_timer *t,
+                          fast_timer_function_type *function,
+                          unsigned long data,
+                          unsigned long delay_us,
+                          const char *name)
+{
+  unsigned long flags;
+  struct fast_timer *tmp;
+
+  D1(printk("sft %s %d us\n", name, delay_us));
+
+  save_flags(flags);
+  cli();
+
+  do_gettimeofday_fast(&t->tv_set);
+  tmp = fast_timer_list;
+
+  SANITYCHECK({ /* Check so this is not in the list already... */
+    while (tmp != NULL)
+    {
+      if (tmp == t)
+      {
+        printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
+        sanity_failed++;
+        return;
+      }
+      else
+      {
+        tmp = tmp->next;
+      }
+    }
+    tmp = fast_timer_list;
+  });
+
+  t->delay_us = delay_us;
+  t->function = function;
+  t->data = data;
+  t->name = name;
+
+  t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
+  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
+  if (t->tv_expires.tv_usec > 1000000)
+  {
+    t->tv_expires.tv_usec -= 1000000;
+    t->tv_expires.tv_sec++;
+  }
+#ifdef FAST_TIMER_LOG
+  timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
+#endif
+  fast_timers_added++;
+
+  /* Check if this should timeout before anything else */
+  if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
+  {
+    /* Put first in list and modify the timer value */
+    t->prev = NULL;
+    t->next = fast_timer_list;
+    if (fast_timer_list)
+    {
+      fast_timer_list->prev = t;
+    }
+    fast_timer_list = t;
+#ifdef FAST_TIMER_LOG
+    timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+    start_timer1(delay_us);
+  } else {
+    /* Put in correct place in list */
+    while (tmp->next &&
+           timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
+    {
+      tmp = tmp->next;
+    }
+    /* Insert t after tmp */
+    t->prev = tmp;
+    t->next = tmp->next;
+    if (tmp->next)
+    {
+      tmp->next->prev = t;
+    }
+    tmp->next = t;
+  }
+
+  D2(printk("start_one_shot_timer: %d us done\n", delay_us));
+
+  restore_flags(flags);
+} /* start_one_shot_timer */
+
+static inline int fast_timer_pending (const struct fast_timer * t)
+{
+  return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
+}
+
+static inline int detach_fast_timer (struct fast_timer *t)
+{
+  struct fast_timer *next, *prev;
+  if (!fast_timer_pending(t))
+    return 0;
+  next = t->next;
+  prev = t->prev;
+  if (next)
+    next->prev = prev;
+  if (prev)
+    prev->next = next;
+  else
+    fast_timer_list = next;
+  fast_timers_deleted++;
+  return 1;
+}
+
+int del_fast_timer(struct fast_timer * t)
+{
+  unsigned long flags;
+  int ret;
+  
+  save_flags(flags);
+  cli();
+  ret = detach_fast_timer(t);
+  t->next = t->prev = NULL;
+  restore_flags(flags);
+  return ret;
+} /* del_fast_timer */
+
+
+/* Interrupt routines or functions called in interrupt context */
+
+/* Timer 1 interrupt handler */
+
+static void
+timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+  struct fast_timer *t;
+  unsigned long flags;
+
+  save_flags(flags);
+  cli();
+
+  /* Clear timer1 irq */
+  *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
+
+  /* First stop timer, then ack interrupt */
+  /* Stop timer */
+  *R_TIMER_CTRL = r_timer_ctrl_shadow =
+    (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
+    IO_STATE(R_TIMER_CTRL, tm1, stop_ld);
+
+  /* Ack interrupt */
+  *R_TIMER_CTRL =  r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr);
+
+  fast_timer_running = 0;
+  fast_timer_ints++;
+
+  restore_flags(flags);
+
+  t = fast_timer_list;
+  while (t)
+  {
+    struct timeval tv;
+
+    /* Has it really expired? */
+    do_gettimeofday_fast(&tv);
+    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
+
+    if (timeval_cmp(&t->tv_expires, &tv) <= 0)
+    {
+      /* Yes it has expired */
+#ifdef FAST_TIMER_LOG
+      timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
+#endif
+      fast_timers_expired++;
+
+      /* Remove this timer before call, since it may reuse the timer */
+      save_flags(flags);
+      cli();
+      if (t->prev)
+      {
+        t->prev->next = t->next;
+      }
+      else
+      {
+        fast_timer_list = t->next;
+      }
+      if (t->next)
+      {
+        t->next->prev = t->prev;
+      }
+      t->prev = NULL;
+      t->next = NULL;
+      restore_flags(flags);
+
+      if (t->function != NULL)
+      {
+        t->function(t->data);
+      }
+      else
+      {
+        DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints);
+      }
+    }
+    else
+    {
+      /* Timer is to early, let's set it again using the normal routines */
+      D1(printk(".\n"));
+    }
+
+    save_flags(flags);
+    cli();
+    if ((t = fast_timer_list) != NULL)
+    {
+      /* Start next timer.. */
+      long us;
+      struct timeval tv;
+
+      do_gettimeofday_fast(&tv);
+      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
+            t->tv_expires.tv_usec - tv.tv_usec);
+      if (us > 0)
+      {
+        if (!fast_timer_running)
+        {
+#ifdef FAST_TIMER_LOG
+          timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+          start_timer1(us);
+        }
+        restore_flags(flags);
+        break;
+      }
+      else
+      {
+        /* Timer already expired, let's handle it better late than never.
+         * The normal loop handles it
+         */
+        D1(printk("e! %d\n", us));
+      }
+    }
+    restore_flags(flags);
+  }
+
+  if (!t)
+  {
+    D1(printk("t1 stop!\n"));
+  }
+}
+
+static void wake_up_func(unsigned long data)
+{
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t  *sleep_wait_p = (wait_queue_head_t*)data;
+#else
+  struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
+#endif
+  wake_up(sleep_wait_p);
+}
+
+
+/* Useful API */
+
+void schedule_usleep(unsigned long us)
+{
+  struct fast_timer t;
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t sleep_wait;
+  DECLARE_WAITQUEUE(wait, current);
+#else
+  struct wait_queue *sleep_wait = NULL;
+  struct wait_queue wait = { current, NULL };
+#endif
+
+  D1(printk("schedule_usleep(%d)\n", us));
+  add_wait_queue(&sleep_wait, &wait);
+  set_current_state(TASK_INTERRUPTIBLE);
+  start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
+                       "usleep");
+  schedule();
+  set_current_state(TASK_RUNNING);
+  remove_wait_queue(&sleep_wait, &wait);
+  D1(printk("done schedule_usleep(%d)\n", us));
+}
+
+#ifdef CONFIG_PROC_FS
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               );
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static struct proc_dir_entry *fasttimer_proc_entry;
+#else
+static struct proc_dir_entry fasttimer_proc_entry =
+{
+  0, 9, "fasttimer",
+  S_IFREG | S_IRUGO, 1, 0, 0,
+  0, NULL /* ops -- default to array */,
+  &proc_fasttimer_read /* get_info */,
+};
+#endif
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_PROC_FS
+
+/* This value is very much based on testing */
+#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
+
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               )
+{
+  unsigned long flags;
+  int i = 0;
+  int num_to_show;
+  struct timeval tv;
+  struct fast_timer *t, *nextt;
+  static char *bigbuf = NULL;
+  static unsigned long used;
+
+  if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
+  {
+    used = 0;
+    bigbuf[0] = '\0';
+    return 0;
+  }
+
+  if (!offset || !used)
+  {
+    do_gettimeofday_fast(&tv);
+
+    used = 0;
+    used += sprintf(bigbuf + used, "Fast timers added:     %i\n",
+                    fast_timers_added);
+    used += sprintf(bigbuf + used, "Fast timers started:   %i\n",
+                    fast_timers_started);
+    used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
+                    fast_timer_ints);
+    used += sprintf(bigbuf + used, "Fast timers expired:   %i\n",
+                    fast_timers_expired);
+    used += sprintf(bigbuf + used, "Fast timers deleted:   %i\n",
+                    fast_timers_deleted);
+    used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
+                    fast_timer_running ? "yes" : "no");
+    used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
+                    (unsigned long)tv.tv_sec,
+                    (unsigned long)tv.tv_usec);
+#ifdef FAST_TIMER_SANITY_CHECKS
+    used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
+                    sanity_failed);
+#endif
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef DEBUG_LOG_INCLUDED
+    {
+      int end_i = debug_log_cnt;
+      i = 0;
+
+      if (debug_log_cnt_wrapped)
+      {
+        i = debug_log_cnt;
+      }
+
+      while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
+             used+100 < BIG_BUF_SIZE)
+      {
+        used += sprintf(bigbuf + used, debug_log_string[i],
+                        debug_log_value[i]);
+        i = (i+1) % DEBUG_LOG_MAX;
+      }
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
+    {
+      int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
+
+#if 1 //ndef FAST_TIMER_LOG
+      used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i"
+                      "\n",
+                      timer_div_settings[cur],
+                      timer_freq_settings[cur],
+                      timer_delay_settings[cur]
+                      );
+#endif
+#ifdef FAST_TIMER_LOG
+      t = &timer_started_log[cur];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+#endif
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef FAST_TIMER_LOG
+    num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+    num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    used += sprintf(bigbuf + used, "Active timers:\n");
+    save_flags(flags);
+    cli();
+    t = fast_timer_list;
+    while (t != NULL && (used+100 < BIG_BUF_SIZE))
+    {
+      nextt = t->next;
+      restore_flags(flags);
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+/*                      " func: 0x%08lX" */
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+/*                      , t->function */
+                      );
+      cli();
+      if (t->next != nextt)
+      {
+        printk("timer removed!\n");
+      }
+      t = nextt;
+    }
+    restore_flags(flags);
+  }
+
+  if (used - offset < len)
+  {
+    len = used - offset;
+  }
+
+  memcpy(buf, bigbuf + offset, len);
+  *start = buf;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  *eof = 1;
+#endif
+
+  return len;
+}
+#endif /* PROC_FS */
+
+#ifdef FAST_TIMER_TEST
+static volatile unsigned long i = 0;
+static volatile int num_test_timeout = 0;
+static struct fast_timer tr[10];
+static int exp_num[10];
+
+static struct timeval tv_exp[100];
+
+static void test_timeout(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+
+  num_test_timeout++;
+}
+
+static void test_timeout1(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+  if (data < 7)
+  {
+    start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1");
+    i++;
+  }
+  num_test_timeout++;
+}
+
+DP(
+static char buf0[2000];
+static char buf1[2000];
+static char buf2[2000];
+static char buf3[2000];
+static char buf4[2000];
+);
+
+static char buf5[6000];
+static int j_u[1000];
+
+static void fast_timer_test(void)
+{
+  int prev_num;
+  int j;
+
+  struct timeval tv, tv0, tv1, tv2;
+
+  printk("fast_timer_test() start\n");
+  do_gettimeofday_fast(&tv);
+
+  for (j = 0; j < 1000; j++)
+  {
+    j_u[j] = GET_JIFFIES_USEC();
+  }
+  for (j = 0; j < 100; j++)
+  {
+    do_gettimeofday_fast(&tv_exp[j]);
+  }
+  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
+
+  for (j = 0; j < 1000; j++)
+  {
+    printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
+    j += 4;
+  }
+  for (j = 0; j < 100; j++)
+  {
+    printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
+           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
+           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
+           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
+           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
+           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
+    j += 4;
+  }
+  do_gettimeofday_fast(&tv0);
+  start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0");
+  DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1");
+  DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2");
+  DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3");
+  DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx");
+  DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0));
+  i++;
+  do_gettimeofday_fast(&tv1);
+
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+
+  prev_num = num_test_timeout;
+  while (num_test_timeout < i)
+  {
+    if (num_test_timeout != prev_num)
+    {
+      prev_num = num_test_timeout;
+    }
+  }
+  do_gettimeofday_fast(&tv2);
+  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
+  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
+  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
+  DP(printk("buf0:\n");
+     printk(buf0);
+     printk("buf1:\n");
+     printk(buf1);
+     printk("buf2:\n");
+     printk(buf2);
+     printk("buf3:\n");
+     printk(buf3);
+     printk("buf4:\n");
+     printk(buf4);
+  );
+  printk("buf5:\n");
+  printk(buf5);
+
+  printk("timers set:\n");
+  for(j = 0; j<i; j++)
+  {
+    struct fast_timer *t = &tr[j];
+    printk("%-10s set: %6is %06ius exp: %6is %06ius "
+           "data: 0x%08X func: 0x%08X\n",
+           t->name,
+           t->tv_set.tv_sec,
+           t->tv_set.tv_usec,
+           t->tv_expires.tv_sec,
+           t->tv_expires.tv_usec,
+           t->data,
+           t->function
+           );
+
+    printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
+           t->delay_us,
+           tv_exp[j].tv_sec,
+           tv_exp[j].tv_usec,
+           exp_num[j],
+           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
+  }
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+  printk("buf5 after all done:\n");
+  printk(buf5);
+  printk("fast_timer_test() done\n");
+}
+#endif
+
+
+void fast_timer_init(void)
+{
+  /* For some reason, request_irq() hangs when called froom time_init() */
+  if (!fast_timer_is_init)
+  {
+#if 0 && defined(FAST_TIMER_TEST)
+    int i;
+#endif
+
+    printk("fast_timer_init()\n");
+
+#if 0 && defined(FAST_TIMER_TEST)
+    for (i = 0; i <= TIMER0_DIV; i++)
+    {
+      /* We must be careful not to get overflow... */
+      printk("%3i %6u\n", i, timer0_value_us[i]);
+    }
+#endif
+#ifdef CONFIG_PROC_FS
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+   if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
+     fasttimer_proc_entry->read_proc = proc_fasttimer_read;
+#else
+    proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
+#endif
+#endif /* PROC_FS */
+    if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ,
+                   "fast timer int", NULL))
+    {
+      printk("err: timer1 irq\n");
+    }
+    fast_timer_is_init = 1;
+#ifdef FAST_TIMER_TEST
+    printk("do test\n");
+    fast_timer_test();
+#endif
+  }
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/kgdb.c linux-bk/arch/cris/kernel/kgdb.c
--- linux-2.4.19/arch/cris/kernel/kgdb.c	2001-11-09 21:58:02.000000000 +0000
+++ linux-bk/arch/cris/kernel/kgdb.c	2002-11-22 15:35:33.000000000 +0000
@@ -18,6 +18,9 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.7  2002/07/12 09:14:56  bjornw
+*! Corrected typo
+*!
 *! Revision 1.6  2001/10/09 13:10:03  matsfg
 *! Added $ on registers and removed some underscores
 *!
@@ -55,7 +58,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.6 2001/10/09 13:10:03 matsfg Exp $
+*! $Id: kgdb.c,v 1.7 2002/07/12 09:14:56 bjornw Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -1064,7 +1067,7 @@
 					int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
 					int status;
 #ifdef PROCESS_SUPPORT
-					if (current_thread_g =! executing_task)
+					if (current_thread_g != executing_task)
 						status = write_stack_register (current_thread_g, regno, suffix+1);
 					else
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/setup.c linux-bk/arch/cris/kernel/setup.c
--- linux-2.4.19/arch/cris/kernel/setup.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/kernel/setup.c	2002-11-22 15:35:33.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.24 2001/12/07 17:03:19 bjornw Exp $
+/* $Id: setup.c,v 1.26 2002/06/04 07:57:56 jonashg Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -169,20 +169,18 @@
 
 	*cmdline_p = command_line;
 
-	if (romfs_in_flash) {
-		strncpy(command_line, "root=", COMMAND_LINE_SIZE);
-		strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
+	strncpy(command_line, "root=", COMMAND_LINE_SIZE);
+	strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
 			COMMAND_LINE_SIZE-5);
 
-		/* Save command line copy for /proc/cmdline */
-
-		memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
-		saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-	}
+	/* Save command line copy for /proc/cmdline */
+	
+	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	/* give credit for the CRIS port */
 
-	printk("Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n");
+	printk("Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n");
 
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/kernel/traps.c linux-bk/arch/cris/kernel/traps.c
--- linux-2.4.19/arch/cris/kernel/traps.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-bk/arch/cris/kernel/traps.c	2002-11-22 15:35:33.000000000 +0000
@@ -230,8 +230,12 @@
 #endif	
 }
 
-/* This is normally the 'Oops' routine */
+void dump_stack(void)
+{
+	show_stack(NULL);
+}
 
+/* This is normally the 'Oops' routine */
 void 
 die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/lib/dram_init.S linux-bk/arch/cris/lib/dram_init.S
--- linux-2.4.19/arch/cris/lib/dram_init.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-bk/arch/cris/lib/dram_init.S	2002-11-22 15:35:27.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.10 2001/10/04 12:00:21 martinnn Exp $
+/* $Id: dram_init.S,v 1.12 2002/08/09 11:37:37 orjanf Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,12 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.12  2002/08/09 11:37:37  orjanf
+ * Added double initialization work-around for Samsung SDRAMs.
+ *
+ * Revision 1.11  2002/06/04 11:43:21  starvik
+ * Check if mrs_data is specified in kernelconfig (necessary for MCM)
+ *
  * Revision 1.10  2001/10/04 12:00:21  martinnn
  * Added missing underscores.
  *
@@ -70,7 +76,11 @@
 
 	move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0
 	move.d   $r0, [R_DRAM_TIMING]
-#else	
+#else
+	;; Samsung SDRAMs seem to require to be initialized twice to work properly.
+	moveq    2, $r6	
+_sdram_init:
+	
 	; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
 	
 	; Bank configuration
@@ -82,6 +92,12 @@
 	; CAS latency = 3 && bus_width = 32 => 0x60
 	; CAS latency = 2 && bus_width = 16 => 0x20
 	; CAS latency = 3 && bus_width = 16 => 0x30
+
+	; Check if value is already supplied in kernel config
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r2
+	and.d    0x00ff0000, $r2
+	bne	 _set_timing
+	lsrq     16, $r2
 	
 	move.d   0x40, $r2       ; Assume 32 bits and CAS latency = 2
 	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
@@ -142,6 +158,9 @@
 	bne      1b
 	nop
 	move.d   $r5, [R_SDRAM_TIMING]
+	subq     1, $r6
+	bne      _sdram_init
+	nop
 	ba       _sdram_commands_end
 	nop
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/lib/hw_settings.S linux-bk/arch/cris/lib/hw_settings.S
--- linux-2.4.19/arch/cris/lib/hw_settings.S	2001-07-04 18:50:39.000000000 +0000
+++ linux-bk/arch/cris/lib/hw_settings.S	2002-11-22 15:35:30.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * $Id: hw_settings.S,v 1.3 2001/04/21 17:02:46 bjornw Exp $
+ * $Id: hw_settings.S,v 1.4 2002/07/04 16:58:56 pkj Exp $
  * 
  * This table is used by some tools to extract hardware parameters.
  * The table should be included in the kernel and the decompressor.
@@ -16,8 +16,8 @@
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
 	
-	.ascii "HW_PARAM_MAGIC" ; Magic number
-	.dword 0xc0004000	; Kernel start address
+	.ascii "HW_PARAM_MAGIC"					; Magic number
+	.dword CONFIG_ETRAX_DRAM_VIRTUAL_BASE | 0x80004000	; Kernel start address
 
 	; Debug port
 #ifdef CONFIG_ETRAX_DEBUG_PORT0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/cris/mm/fault.c linux-bk/arch/cris/mm/fault.c
--- linux-2.4.19/arch/cris/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/cris/mm/fault.c	2002-11-22 15:35:27.000000000 +0000
@@ -6,6 +6,9 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.21  2002/05/28 14:24:56  bjornw
+ *  Corrected typo
+ *
  *  Revision 1.20  2001/11/22 13:34:06  bjornw
  *  * Bug workaround (LX TR89): force a rerun of the whole of an interrupted
  *    unaligned write, because the second half of the write will be corrupted
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/Makefile linux-bk/arch/i386/Makefile
--- linux-2.4.19/arch/i386/Makefile	2001-04-12 19:20:31.000000000 +0000
+++ linux-bk/arch/i386/Makefile	2002-11-22 15:35:28.000000000 +0000
@@ -83,7 +83,7 @@
 endif
 
 ifdef CONFIG_MCYRIXIII
-CFLAGS += -march=i586
+CFLAGS += -march=i486 -malign-functions=0 -malign-jumps=0 -malign-loops=0
 endif
 
 HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/boot/compressed/misc.c linux-bk/arch/i386/boot/compressed/misc.c
--- linux-2.4.19/arch/i386/boot/compressed/misc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/boot/compressed/misc.c	2002-11-22 15:35:31.000000000 +0000
@@ -9,6 +9,8 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 
+#define STANDALONE
+
 #include <linux/linkage.h>
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
@@ -124,10 +126,6 @@
 static int vidport;
 static int lines, cols;
 
-#ifdef CONFIG_MULTIQUAD
-static void * const xquad_portio = NULL;
-#endif
-
 #include "../../../../lib/inflate.c"
 
 static void *malloc(int size)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/config.in linux-bk/arch/i386/config.in
--- linux-2.4.19/arch/i386/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/config.in	2002-11-22 15:35:27.000000000 +0000
@@ -5,7 +5,6 @@
 mainmenu_name "Linux Kernel Configuration"
 
 define_bool CONFIG_X86 y
-define_bool CONFIG_ISA y
 define_bool CONFIG_SBUS n
 
 define_bool CONFIG_UID16 y
@@ -54,6 +53,7 @@
    define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
    define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 else
    define_bool CONFIG_X86_WP_WORKS_OK y
    define_bool CONFIG_X86_INVLPG y
@@ -69,99 +69,112 @@
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586TSC" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M586MMX" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK n
 fi
 if [ "$CONFIG_M686" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_PPRO_FENCE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MPENTIUM4" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 7
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MK6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
 fi
 if [ "$CONFIG_MK7" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 6
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_GOOD_APIC y
    define_bool CONFIG_X86_USE_3DNOW y
    define_bool CONFIG_X86_PGE y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MELAN" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 4
    define_bool CONFIG_X86_USE_STRING_486 y
    define_bool CONFIG_X86_ALIGNMENT_16 y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MCYRIXIII" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_USE_3DNOW y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
 fi
 if [ "$CONFIG_MCRUSOE" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIPC6" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIP2" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 if [ "$CONFIG_MWINCHIP3D" = "y" ]; then
    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
    define_bool CONFIG_X86_ALIGNMENT_16 y
-   define_bool CONFIG_X86_TSC y
+   define_bool CONFIG_X86_HAS_TSC y
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
+   define_bool CONFIG_X86_F00F_WORKS_OK y
 fi
 
 bool 'Machine Check Exception' CONFIG_X86_MCE
@@ -177,14 +190,19 @@
 	"off    CONFIG_NOHIGHMEM \
 	 4GB    CONFIG_HIGHMEM4G \
 	 64GB   CONFIG_HIGHMEM64G" off
-if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
+if [ "$CONFIG_HIGHMEM4G" = "y" -o "$CONFIG_HIGHMEM64G" = "y" ]; then
    define_bool CONFIG_HIGHMEM y
+else
+   define_bool CONFIG_HIGHMEM n
 fi
 if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
-   define_bool CONFIG_HIGHMEM y
    define_bool CONFIG_X86_PAE y
 fi
 
+if [ "$CONFIG_HIGHMEM" = "y" ]; then
+   bool 'HIGHMEM I/O support' CONFIG_HIGHIO
+fi
+
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -201,6 +219,11 @@
    bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
 fi
 
+bool 'Unsynced TSC support' CONFIG_X86_TSC_DISABLE
+if [ "$CONFIG_X86_TSC_DISABLE" != "y" -a "$CONFIG_X86_HAS_TSC" = "y" ]; then
+   define_bool CONFIG_X86_TSC y
+fi
+
 if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
    define_bool CONFIG_HAVE_DEC_LOCK y
 fi
@@ -218,6 +241,7 @@
    define_bool CONFIG_X86_VISWS_APIC y
    define_bool CONFIG_X86_LOCAL_APIC y
    define_bool CONFIG_PCI y
+   define_bool CONFIG_ISA n
 else
    if [ "$CONFIG_SMP" = "y" ]; then
       define_bool CONFIG_X86_IO_APIC y
@@ -236,6 +260,7 @@
          define_bool CONFIG_PCI_DIRECT y
       fi
    fi
+   bool 'ISA bus support' CONFIG_ISA
 fi
 
 source drivers/pci/Config.in
@@ -366,14 +391,16 @@
 fi
 endmenu
 
-mainmenu_option next_comment
-comment 'Old CD-ROM drivers (not SCSI, not IDE)'
-
-bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
-   source drivers/cdrom/Config.in
+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
-endmenu
 
 #
 # input before char - char/joystick depends on it. As does USB.
@@ -417,6 +444,7 @@
 
 bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
 if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
+   bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
    bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
@@ -426,3 +454,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/defconfig linux-bk/arch/i386/defconfig
--- linux-2.4.19/arch/i386/defconfig	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/defconfig	2002-11-22 15:35:24.000000000 +0000
@@ -617,7 +617,8 @@
 CONFIG_DRM_TDFX=y
 # CONFIG_DRM_R128 is not set
 CONFIG_DRM_RADEON=y
-# CONFIG_DRM_I810 is not set
+CONFIG_DRM_I810=y
+CONFIG_DRM_I810_XFREE_41=y
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/Makefile linux-bk/arch/i386/kernel/Makefile
--- linux-2.4.19/arch/i386/kernel/Makefile	2001-11-09 22:21:21.000000000 +0000
+++ linux-bk/arch/i386/kernel/Makefile	2002-11-22 15:35:25.000000000 +0000
@@ -14,7 +14,7 @@
 
 O_TARGET := kernel.o
 
-export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o
+export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/apic.c linux-bk/arch/i386/kernel/apic.c
--- linux-2.4.19/arch/i386/kernel/apic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/apic.c	2002-11-22 15:35:30.000000000 +0000
@@ -29,6 +29,7 @@
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
+#include <asm/smpboot.h>
 
 /* Using APIC to generate smp_local_timer_interrupt? */
 int using_apic_timer = 0;
@@ -291,14 +292,13 @@
 	 * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
 	 * document number 292116).  So here it goes...
 	 */
-
-	if (!clustered_apic_mode) {
+	if (clustered_apic_mode != CLUSTERED_APIC_NUMAQ) {
 		/*
-		 * In clustered apic mode, the firmware does this for us 
-		 * Put the APIC into flat delivery mode.
-		 * Must be "all ones" explicitly for 82489DX.
+		 * For NUMA-Q (clustered apic logical), the firmware does this
+		 * for us. Otherwise put the APIC into clustered or flat
+		 * delivery mode. Must be "all ones" explicitly for 82489DX.
 		 */
-		apic_write_around(APIC_DFR, 0xffffffff);
+		apic_write_around(APIC_DFR, APIC_DFR_FLAT);
 
 		/*
 		 * Set up the logical destination ID.
@@ -1050,7 +1050,7 @@
 /*
  * Local APIC timer interrupt. This is the most natural way for doing
  * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesnt support APIC timers]
+ * broadcast interrupts too. [in case the hw doesn't support APIC timers]
  *
  * [ if a single-CPU system runs an SMP kernel then we call the local
  *   interrupt as well. Thus we cannot inline the local irq ... ]
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/apm.c linux-bk/arch/i386/kernel/apm.c
--- linux-2.4.19/arch/i386/kernel/apm.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/apm.c	2002-11-22 15:35:23.000000000 +0000
@@ -847,6 +847,7 @@
 			case 1: apm_idle_done = 1;
 				break;
 			default: /* BIOS refused */
+				break;
 			}
 		}
 		if (original_pm_idle)
@@ -862,14 +863,6 @@
 		apm_do_busy();
 }
 
-#ifdef CONFIG_SMP
-static int apm_magic(void * unused)
-{
-	while (1)
-		schedule();
-}
-#endif
-
 /**
  *	apm_power_off	-	ask the BIOS to power off
  *
@@ -897,10 +890,11 @@
 	 */
 #ifdef CONFIG_SMP
 	/* Some bioses don't like being called from CPU != 0 */
-	while (cpu_number_map(smp_processor_id()) != 0) {
-		kernel_thread(apm_magic, NULL,
-			CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
+	if (cpu_number_map(smp_processor_id()) != 0) {
+		current->cpus_allowed = 1;
 		schedule();
+		if (unlikely(cpu_number_map(smp_processor_id()) != 0))
+			BUG();
 	}
 #endif
 	if (apm_info.realmode_power_off)
@@ -1661,6 +1655,21 @@
 	strcpy(current->comm, "kapmd");
 	sigfillset(&current->blocked);
 
+#ifdef CONFIG_SMP
+	/* 2002/08/01 - WT
+	 * This is to avoid random crashes at boot time during initialization
+	 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
+	 * Some bioses don't like being called from CPU != 0.
+	 * Method suggested by Ingo Molnar.
+	 */
+	if (cpu_number_map(smp_processor_id()) != 0) {
+		current->cpus_allowed = 1;
+		schedule();
+		if (unlikely(cpu_number_map(smp_processor_id()) != 0))
+			BUG();
+	}
+#endif
+	
 	if (apm_info.connection_version == 0) {
 		apm_info.connection_version = apm_info.bios.version;
 		if (apm_info.connection_version > 0x100) {
@@ -1707,7 +1716,7 @@
 		}
 	}
 
-	if (debug && (smp_num_cpus == 1)) {
+	if (debug) {
 		error = apm_get_power_status(&bx, &cx, &dx);
 		if (error)
 			printk(KERN_INFO "apm: power status not available\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/dmi_scan.c linux-bk/arch/i386/kernel/dmi_scan.c
--- linux-2.4.19/arch/i386/kernel/dmi_scan.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/dmi_scan.c	2002-11-22 15:35:28.000000000 +0000
@@ -31,7 +31,7 @@
 	if(!s)
 		return "";
 	s--;
-	while(s>0)
+	while(s>0 && *bp)
 	{
 		bp+=strlen(bp);
 		bp++;
@@ -50,7 +50,7 @@
 	u8 *buf;
 	struct dmi_header *dm;
 	u8 *data;
-	int i=1;
+	int i=0;
 		
 	buf = bt_ioremap(base, len);
 	if(buf==NULL)
@@ -59,28 +59,23 @@
 	data = buf;
 
 	/*
- 	 *	Stop when we see al the items the table claimed to have
+ 	 *	Stop when we see all the items the table claimed to have
  	 *	OR we run off the end of the table (also happens)
  	 */
  
-	while(i<num && (data - buf) < len)
+	while(i<num && data-buf+sizeof(struct dmi_header)<=len)
 	{
 		dm=(struct dmi_header *)data;
-	
 		/*
-		 *	Avoid misparsing crud if the length of the last
-	 	 *	record is crap 
+		 *  We want to know the total length (formated area and strings)
+		 *  before decoding to make sure we won't run off the table in
+		 *  dmi_decode or dmi_string
 		 */
-		if((data-buf+dm->length) >= len)
-			break;
-		decode(dm);		
 		data+=dm->length;
-		/*
-		 *	Don't go off the end of the data if there is
-	 	 *	stuff looking like string fill past the end
-	 	 */
-		while((data-buf) < len && (*data || data[1]))
+		while(data-buf<len-1 && (data[0] || data[1]))
 			data++;
+		if(data-buf<len-1)
+			decode(dm);
 		data+=2;
 		i++;
 	}
@@ -89,11 +84,20 @@
 }
 
 
+inline static int __init dmi_checksum(u8 *buf)
+{
+	u8 sum=0;
+	int a;
+	
+	for(a=0; a<15; a++)
+		sum+=buf[a];
+	return (sum==0);
+}
+
 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
 {
-	unsigned char buf[20];
-	long fp=0xE0000L;
-	fp -= 16;
+	u8 buf[15];
+	u32 fp=0xF0000;
 
 #ifdef CONFIG_SIMNOW
 	/*
@@ -105,24 +109,30 @@
  	
 	while( fp < 0xFFFFF)
 	{
-		fp+=16;
-		isa_memcpy_fromio(buf, fp, 20);
-		if(memcmp(buf, "_DMI_", 5)==0)
+		isa_memcpy_fromio(buf, fp, 15);
+		if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
 		{
 			u16 num=buf[13]<<8|buf[12];
 			u16 len=buf[7]<<8|buf[6];
 			u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
 
-			dmi_printk((KERN_INFO "DMI %d.%d present.\n",
-				buf[14]>>4, buf[14]&0x0F));
+			/*
+			 * DMI version 0.0 means that the real version is taken from
+			 * the SMBIOS version, which we don't know at this point.
+			 */
+			if(buf[14]!=0)
+				dmi_printk((KERN_INFO "DMI %d.%d present.\n",
+					buf[14]>>4, buf[14]&0x0F));
+			else
+				dmi_printk((KERN_INFO "DMI present.\n"));
 			dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
-				buf[13]<<8|buf[12],
-				buf[7]<<8|buf[6]));
+				num, len));
 			dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
-				buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]));
+				base));
 			if(dmi_table(base,len, num, decode)==0)
 				return 0;
 		}
+		fp+=16;
 	}
 	return -1;
 }
@@ -190,7 +200,6 @@
  *	KT7 series. On these it seems the newer BIOS has fixed them. The
  *	rule needs to be improved to match specific BIOS revisions with
  *	corruption problems
- */ 
  
 static __init int disable_ide_dma(struct dmi_blacklist *d)
 {
@@ -204,6 +213,7 @@
 #endif	
 	return 0;
 }
+ */ 
 
 /* 
  * Reboot options and system auto-detection code provided by
@@ -475,6 +485,22 @@
 	return 0;
 }
 
+/*
+ * Work around broken HP Pavilion Notebooks which assign USB to
+ * IRQ 9 even though it is actually wired to IRQ 11
+ */
+static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_PCI
+	extern int broken_hp_bios_irq9;
+	if (broken_hp_bios_irq9 == 0)
+	{
+		broken_hp_bios_irq9 = 1;
+		printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
+	}
+#endif
+	return 0;
+}
 
 /*
  *	Simple "print if true" callback
@@ -564,6 +590,17 @@
 			MATCH(DMI_BIOS_VERSION, "Version1.01"),
 			NO_MATCH, NO_MATCH,
 			} },
+	{ apm_is_horked, "Intel D850MD", { /* APM crashes */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
+			MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"),
+			NO_MATCH, NO_MATCH,
+			} },
+	{ apm_is_horked, "Dell XPS-Z", { /* APM crashes */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
+			MATCH(DMI_BIOS_VERSION, "A11"),
+			MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
+			NO_MATCH,
+			} },
 	{ apm_is_horked, "Sharp PC-PJ/AX", { /* APM crashes */
 			MATCH(DMI_SYS_VENDOR, "SHARP"),
 			MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
@@ -635,6 +672,12 @@
 			MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
 			} },
 	
+	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "WXP01Z3"),
+			MATCH(DMI_BIOS_DATE, "10/26/01"), NO_MATCH
+			} },
+	
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-F104K */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "R0204K2"),
@@ -738,7 +781,14 @@
 			NO_MATCH, NO_MATCH
 			} },
 	 
-			
+	{ fix_broken_hp_bios_irq9, "HP Pavilion N5400 Series Laptop", {
+			MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			MATCH(DMI_BIOS_VERSION, "GE.M1.03"),
+			MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
+			MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
+			} },
+ 
+
 	/*
 	 *	Generic per vendor APM settings
 	 */
@@ -793,59 +843,43 @@
 static void __init dmi_decode(struct dmi_header *dm)
 {
 	u8 *data = (u8 *)dm;
-	char *p;
 	
 	switch(dm->type)
 	{
 		case  0:
-			p=dmi_string(dm,data[4]);
-			if(*p)
-			{
-				dmi_printk(("BIOS Vendor: %s\n", p));
-				dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
-				dmi_printk(("BIOS Version: %s\n", 
-					dmi_string(dm, data[5])));
-				dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
-				dmi_printk(("BIOS Release: %s\n",
-					dmi_string(dm, data[8])));
-				dmi_save_ident(dm, DMI_BIOS_DATE, 8);
-			}
+			dmi_printk(("BIOS Vendor: %s\n",
+				dmi_string(dm, data[4])));
+			dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
+			dmi_printk(("BIOS Version: %s\n", 
+				dmi_string(dm, data[5])));
+			dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
+			dmi_printk(("BIOS Release: %s\n",
+				dmi_string(dm, data[8])));
+			dmi_save_ident(dm, DMI_BIOS_DATE, 8);
 			break;
-			
 		case 1:
-			p=dmi_string(dm,data[4]);
-			if(*p)
-			{
-				dmi_printk(("System Vendor: %s.\n",p));
-				dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
-				dmi_printk(("Product Name: %s.\n",
-					dmi_string(dm, data[5])));
-				dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
-				dmi_printk(("Version %s.\n",
-					dmi_string(dm, data[6])));
-				dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
-				dmi_printk(("Serial Number %s.\n",
-					dmi_string(dm, data[7])));
-			}
+			dmi_printk(("System Vendor: %s\n",
+				dmi_string(dm, data[4])));
+			dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
+			dmi_printk(("Product Name: %s\n",
+				dmi_string(dm, data[5])));
+			dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
+			dmi_printk(("Version: %s\n",
+				dmi_string(dm, data[6])));
+			dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
+			dmi_printk(("Serial Number: %s\n",
+				dmi_string(dm, data[7])));
 			break;
 		case 2:
-			p=dmi_string(dm,data[4]);
-			if(*p)
-			{
-				dmi_printk(("Board Vendor: %s.\n",p));
-				dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
-				dmi_printk(("Board Name: %s.\n",
-					dmi_string(dm, data[5])));
-				dmi_save_ident(dm, DMI_BOARD_NAME, 5);
-				dmi_printk(("Board Version: %s.\n",
-					dmi_string(dm, data[6])));
-				dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
-			}
-			break;
-		case 3:
-			p=dmi_string(dm,data[8]);
-			if(*p && *p!=' ')
-				dmi_printk(("Asset Tag: %s.\n", p));
+			dmi_printk(("Board Vendor: %s\n",
+				dmi_string(dm, data[4])));
+			dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
+			dmi_printk(("Board Name: %s\n",
+				dmi_string(dm, data[5])));
+			dmi_save_ident(dm, DMI_BOARD_NAME, 5);
+			dmi_printk(("Board Version: %s\n",
+				dmi_string(dm, data[6])));
+			dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
 			break;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/entry.S linux-bk/arch/i386/kernel/entry.S
--- linux-2.4.19/arch/i386/kernel/entry.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/entry.S	2002-11-22 15:35:26.000000000 +0000
@@ -63,7 +63,9 @@
 OLDSS		= 0x38
 
 CF_MASK		= 0x00000001
+TF_MASK		= 0x00000100
 IF_MASK		= 0x00000200
+DF_MASK		= 0x00000400
 NT_MASK		= 0x00004000
 VM_MASK		= 0x00020000
 
@@ -140,6 +142,9 @@
 	movl CS(%esp),%edx	# this is eip..
 	movl EFLAGS(%esp),%ecx	# and this is cs..
 	movl %eax,EFLAGS(%esp)	#
+	andl $~(NT_MASK|TF_MASK|DF_MASK), %eax
+	pushl %eax
+	popfl
 	movl %edx,EIP(%esp)	# Now we move them to their "normal" places
 	movl %ecx,CS(%esp)	#
 	movl %esp,%ebx
@@ -161,6 +166,9 @@
 	movl CS(%esp),%edx	# this is eip..
 	movl EFLAGS(%esp),%ecx	# and this is cs..
 	movl %eax,EFLAGS(%esp)	#
+	andl $~(NT_MASK|TF_MASK|DF_MASK), %eax
+	pushl %eax
+	popfl
 	movl %edx,EIP(%esp)	# Now we move them to their "normal" places
 	movl %ecx,CS(%esp)	#
 	movl %esp,%ebx
@@ -622,23 +630,33 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* Reserved for Security */
 	.long SYMBOL_NAME(sys_gettid)
 	.long SYMBOL_NAME(sys_readahead)	/* 225 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for setxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lsetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fsetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for getxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 230 reserved for lgetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fgetxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for listxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for llistxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for flistxattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 235 reserved for removexattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lremovexattr */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fremovexattr */
+	.long SYMBOL_NAME(sys_setxattr)
+	.long SYMBOL_NAME(sys_lsetxattr)
+	.long SYMBOL_NAME(sys_fsetxattr)
+	.long SYMBOL_NAME(sys_getxattr)
+	.long SYMBOL_NAME(sys_lgetxattr)	/* 230 */
+	.long SYMBOL_NAME(sys_fgetxattr)
+	.long SYMBOL_NAME(sys_listxattr)
+	.long SYMBOL_NAME(sys_llistxattr)
+	.long SYMBOL_NAME(sys_flistxattr)
+	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
+	.long SYMBOL_NAME(sys_lremovexattr)
+	.long SYMBOL_NAME(sys_fremovexattr)
  	.long SYMBOL_NAME(sys_tkill)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sendfile64 */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 reserved for futex */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_setaffinity */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_getaffinity */
+	.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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/io_apic.c linux-bk/arch/i386/kernel/io_apic.c
--- linux-2.4.19/arch/i386/kernel/io_apic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/io_apic.c	2002-11-22 15:35:27.000000000 +0000
@@ -32,6 +32,7 @@
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/desc.h>
+#include <asm/smpboot.h>
 
 #undef APIC_LOCKUP_DEBUG
 
@@ -39,6 +40,10 @@
 
 static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
 
+unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
+unsigned char int_delivery_mode = dest_LowestPrio;
+
+
 /*
  * # of IRQ routing registers
  */
@@ -625,10 +630,10 @@
 		 */
 		memset(&entry,0,sizeof(entry));
 
-		entry.delivery_mode = dest_LowestPrio;
-		entry.dest_mode = INT_DELIVERY_MODE;
+		entry.delivery_mode = INT_DELIVERY_MODE;
+		entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
 		entry.mask = 0;				/* enable IRQ */
-		entry.dest.logical.logical_dest = TARGET_CPUS;
+		entry.dest.logical.logical_dest = target_cpus();
 
 		idx = find_irq_entry(apic,pin,mp_INT);
 		if (idx == -1) {
@@ -646,7 +651,6 @@
 		if (irq_trigger(idx)) {
 			entry.trigger = 1;
 			entry.mask = 1;
-			entry.dest.logical.logical_dest = TARGET_CPUS;
 		}
 
 		irq = pin_2_irq(idx, apic, pin);
@@ -654,7 +658,8 @@
 		 * skip adding the timer int on secondary nodes, which causes
 		 * a small but painful rift in the time-space continuum
 		 */
-		if (clustered_apic_mode && (apic != 0) && (irq == 0))
+		if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) 
+			&& (apic != 0) && (irq == 0))
 			continue;
 		else
 			add_pin_to_irq(irq, apic, pin);
@@ -707,16 +712,16 @@
 	 * We use logical delivery to get the timer IRQ
 	 * to the first CPU.
 	 */
-	entry.dest_mode = INT_DELIVERY_MODE;
+	entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
 	entry.mask = 0;					/* unmask IRQ now */
-	entry.dest.logical.logical_dest = TARGET_CPUS;
-	entry.delivery_mode = dest_LowestPrio;
+	entry.dest.logical.logical_dest = target_cpus();
+	entry.delivery_mode = INT_DELIVERY_MODE;
 	entry.polarity = 0;
 	entry.trigger = 0;
 	entry.vector = vector;
 
 	/*
-	 * The timer IRQ doesnt have to know that behind the
+	 * The timer IRQ doesn't have to know that behind the
 	 * scene we have a 8259A-master in AEOI mode ...
 	 */
 	irq_desc[0].handler = &ioapic_edge_irq_type;
@@ -1586,7 +1591,7 @@
 	printk(" failed.\n");
 
 	if (nmi_watchdog) {
-		printk(KERN_WARNING "timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n");
+		printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
 		nmi_watchdog = 0;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/irq.c linux-bk/arch/i386/kernel/irq.c
--- linux-2.4.19/arch/i386/kernel/irq.c	2001-10-25 20:53:46.000000000 +0000
+++ linux-bk/arch/i386/kernel/irq.c	2002-11-22 15:35:24.000000000 +0000
@@ -577,6 +577,20 @@
 	irq_desc_t *desc = irq_desc + irq;
 	struct irqaction * action;
 	unsigned int status;
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	long esp;
+
+	/* Debugging check for stack overflow: is there less than 1KB free? */
+	__asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191));
+	if (unlikely(esp < (sizeof(struct task_struct) + 1024))) {
+		extern void show_stack(unsigned long *);
+
+		printk("do_IRQ: stack overflow: %ld\n",
+			esp - sizeof(struct task_struct));
+		__asm__ __volatile__("movl %%esp,%0" : "=r" (esp));
+		show_stack((void *)esp);
+	}
+#endif
 
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/mpparse.c linux-bk/arch/i386/kernel/mpparse.c
--- linux-2.4.19/arch/i386/kernel/mpparse.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/mpparse.c	2002-11-22 15:35:27.000000000 +0000
@@ -26,6 +26,7 @@
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
+#include <asm/smpboot.h>
 
 /* Have we found an MP table */
 int smp_found_config;
@@ -65,6 +66,8 @@
 /* Bitmask of physically existing CPUs */
 unsigned long phys_cpu_present_map;
 
+unsigned char esr_disable = 0;
+
 /*
  * Intel MP BIOS table parsing routines:
  */
@@ -115,6 +118,8 @@
 		case 0x0F:
 			if (model == 0x00)
 				return("Pentium 4(tm)");
+			if (model == 0x02)
+				return("Pentium 4(tm) XEON(tm)");
 			if (model == 0x0F)
 				return("Special controller");
 	}
@@ -145,7 +150,7 @@
 		return;
 
 	logical_apicid = m->mpc_apicid;
-	if (clustered_apic_mode) {
+	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
 		quad = translation_table[mpc_record]->trans_quad;
 		logical_apicid = (quad << 4) + 
 			(m->mpc_apicid ? m->mpc_apicid << 1 : 1);
@@ -221,11 +226,12 @@
 	if (m->mpc_apicid > MAX_APICS) {
 		printk("Processor #%d INVALID. (Max ID: %d).\n",
 			m->mpc_apicid, MAX_APICS);
+			--num_processors;
 		return;
 	}
 	ver = m->mpc_apicver;
 
-	if (clustered_apic_mode) {
+	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
 		phys_cpu_present_map |= (logical_apicid&0xf) << (4*quad);
 	} else {
 		phys_cpu_present_map |= 1 << m->mpc_apicid;
@@ -248,7 +254,7 @@
 	memcpy(str, m->mpc_bustype, 6);
 	str[6] = 0;
 	
-	if (clustered_apic_mode) {
+	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
 		quad = translation_table[mpc_record]->trans_quad;
 		mp_bus_id_to_node[m->mpc_busid] = quad;
 		mp_bus_id_to_local[m->mpc_busid] = translation_table[mpc_record]->trans_local;
@@ -433,7 +439,7 @@
 	if (!have_acpi_tables)
 		mp_lapic_addr = mpc->mpc_lapic;
 
-	if (clustered_apic_mode && mpc->mpc_oemptr) {
+	if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) {
 		/* We need to process the oem mpc tables to tell us which quad things are in ... */
 		mpc_record = 0;
 		smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, mpc->mpc_oemsize);
@@ -502,6 +508,11 @@
 		}
 		++mpc_record;
 	}
+
+	if (clustered_apic_mode){
+		esr_disable = 1;
+	}
+
 	if (!num_processors)
 		printk(KERN_ERR "SMP mptable: no processors registered!\n");
 	return num_processors;
@@ -815,7 +826,7 @@
 
 /*
  * The Visual Workstation is Intel MP compliant in the hardware
- * sense, but it doesnt have a BIOS(-configuration table).
+ * sense, but it doesn't have a BIOS(-configuration table).
  * No problem for Linux.
  */
 void __init find_visws_smp(void)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-dma.c linux-bk/arch/i386/kernel/pci-dma.c
--- linux-2.4.19/arch/i386/kernel/pci-dma.c	2000-02-14 23:34:21.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-dma.c	2002-11-22 15:35:25.000000000 +0000
@@ -19,7 +19,7 @@
 	void *ret;
 	int gfp = GFP_ATOMIC;
 
-	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+	if (hwdev == NULL || ((u32)hwdev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
 	ret = (void *)__get_free_pages(gfp, get_order(size));
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-i386.c linux-bk/arch/i386/kernel/pci-i386.c
--- linux-2.4.19/arch/i386/kernel/pci-i386.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-i386.c	2002-11-22 15:35:26.000000000 +0000
@@ -136,7 +136,8 @@
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
@@ -303,7 +304,7 @@
 	pcibios_assign_resources();
 }
 
-int pcibios_enable_resources(struct pci_dev *dev)
+int pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -312,6 +313,10 @@
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for(idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+			
 		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);
@@ -347,7 +352,7 @@
 		lat = pcibios_max_latency;
 	else
 		return;
-	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-i386.h linux-bk/arch/i386/kernel/pci-i386.h
--- linux-2.4.19/arch/i386/kernel/pci-i386.h	2001-11-11 18:09:32.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-i386.h	2002-11-22 15:35:23.000000000 +0000
@@ -29,7 +29,7 @@
 extern unsigned int pcibios_max_latency;
 
 void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *);
+int pcibios_enable_resources(struct pci_dev *, int);
 
 /* pci-pc.c */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-irq.c linux-bk/arch/i386/kernel/pci-irq.c
--- linux-2.4.19/arch/i386/kernel/pci-irq.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-irq.c	2002-11-22 15:35:34.000000000 +0000
@@ -22,6 +22,8 @@
 #define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
 #define PIRQ_VERSION 0x0100
 
+int broken_hp_bios_irq9;
+
 static struct irq_routing_table *pirq_table;
 
 /*
@@ -596,6 +598,15 @@
 	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
 	mask &= pcibios_irq_mask;
 
+	/* Work around broken HP Pavilion Notebooks which assign USB to
+	   IRQ 9 even though it is actually wired to IRQ 11 */
+
+	if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) {
+		dev->irq = 11;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+		r->set(pirq_router_dev, dev, pirq, 11);
+	}
+
 	/*
 	 * Find the best IRQ to assign: use the one
 	 * reported by the device if possible.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-pc.c linux-bk/arch/i386/kernel/pci-pc.c
--- linux-2.4.19/arch/i386/kernel/pci-pc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-pc.c	2002-11-22 15:35:29.000000000 +0000
@@ -15,6 +15,7 @@
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/smp.h>
+#include <asm/smpboot.h>
 
 #include "pci-i386.h"
 
@@ -54,11 +55,11 @@
 #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
 	(0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
 
-static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* CONFIG_MULTIQUAD */
+static int pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* CONFIG_MULTIQUAD */
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -82,11 +83,11 @@
 	return 0;
 }
 
-static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* CONFIG_MULTIQUAD */
+static int pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* CONFIG_MULTIQUAD */
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -110,7 +111,69 @@
 	return 0;
 }
 
-#else /* !CONFIG_MULTIQUAD */
+static int pci_conf1_read_mq_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	int result; 
+	u32 data;
+
+	result = pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, &data);
+
+	*value = (u8)data;
+
+	return result;
+}
+
+static int pci_conf1_read_mq_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	int result; 
+	u32 data;
+
+	result = pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, &data);
+
+	*value = (u16)data;
+
+	return result;
+}
+
+static int pci_conf1_read_mq_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	if (!value) 
+		return -EINVAL;
+
+	return pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static int pci_conf1_write_mq_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 1, value);
+}
+
+static int pci_conf1_write_mq_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 2, value);
+}
+
+static int pci_conf1_write_mq_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 
+		PCI_FUNC(dev->devfn), where, 4, value);
+}
+
+static struct pci_ops pci_direct_mq_conf1 = {
+	pci_conf1_read_mq_config_byte,
+	pci_conf1_read_mq_config_word,
+	pci_conf1_read_mq_config_dword,
+	pci_conf1_write_mq_config_byte,
+	pci_conf1_write_mq_config_word,
+	pci_conf1_write_mq_config_dword
+};
+
+#endif /* !CONFIG_MULTIQUAD */
 #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
 	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
 
@@ -118,7 +181,7 @@
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -146,7 +209,7 @@
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -170,8 +233,6 @@
 	return 0;
 }
 
-#endif /* CONFIG_MULTIQUAD */
-
 #undef PCI_CONF1_ADDRESS
 
 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
@@ -179,9 +240,6 @@
 	int result; 
 	u32 data;
 
-	if (!value) 
-		return -EINVAL;
-
 	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 1, &data);
 
@@ -195,9 +253,6 @@
 	int result; 
 	u32 data;
 
-	if (!value) 
-		return -EINVAL;
-
 	result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 2, &data);
 
@@ -208,9 +263,6 @@
 
 static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
-	if (!value) 
-		return -EINVAL;
-
 	return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 4, value);
 }
@@ -253,7 +305,7 @@
 {
 	unsigned long flags;
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	if (dev & 0x10) 
@@ -287,7 +339,7 @@
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
 		return -EINVAL;
 
 	if (dev & 0x10) 
@@ -423,6 +475,12 @@
 			__restore_flags(flags);
 			printk(KERN_INFO "PCI: Using configuration type 1\n");
 			request_region(0xCF8, 8, "PCI conf1");
+
+#ifdef CONFIG_MULTIQUAD			
+			/* Multi-Quad has an extended PCI Conf1 */
+			if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+				return &pci_direct_mq_conf1;
+#endif				
 			return &pci_direct_conf1;
 		}
 		outl (tmp, 0xCF8);
@@ -640,7 +698,7 @@
 	unsigned long flags;
 	unsigned long bx = ((bus << 8) | (dev << 3) | fn);
 
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+	if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -695,7 +753,7 @@
 	unsigned long flags;
 	unsigned long bx = ((bus << 8) | (dev << 3) | fn);
 
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+	if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -750,7 +808,7 @@
 	u32 data;
 
 	if (!value) 
-		return -EINVAL;
+		BUG();
 
 	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 1, &data);
@@ -766,7 +824,7 @@
 	u32 data;
 
 	if (!value) 
-		return -EINVAL;
+		BUG();
 
 	result = pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 2, &data);
@@ -779,7 +837,7 @@
 static int pci_bios_read_config_dword(struct pci_dev *dev, int where, u32 *value)
 {
 	if (!value) 
-		return -EINVAL;
+		BUG();
 	
 	return pci_bios_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 
 		PCI_FUNC(dev->devfn), where, 4, value);
@@ -1227,6 +1285,11 @@
 	pci_read_config_byte(d, PCI_REVISION_ID, &revision);
 	
 	if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
+		/* fix pci bus latency issues resulted by NB bios error
+		   it appears on bug free^Wreduced kt266x's bios forces
+		   NB latency to zero */
+		pci_write_config_byte(d, PCI_LATENCY_TIMER, 0);
+
 		where = 0x95; /* the memory write queue timer register is 
 				 different for the KT266x's: 0x95 not 0x55 */
 	} else if (d->device == PCI_DEVICE_ID_VIA_8363_0 &&
@@ -1245,6 +1308,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 },
@@ -1259,6 +1338,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 }
 };
 
@@ -1281,6 +1361,11 @@
 	 * both PCI BIOS and direct access, with a preference for direct.
 	 */
 
+#ifdef CONFIG_PCI_DIRECT
+	struct pci_ops *tmp = NULL;
+#endif
+
+
 #ifdef CONFIG_PCI_BIOS
 	if ((pci_probe & PCI_PROBE_BIOS) 
 		&& ((pci_root_ops = pci_find_bios()))) {
@@ -1293,7 +1378,8 @@
 
 #ifdef CONFIG_PCI_DIRECT
 	if ((pci_probe & (PCI_PROBE_CONF1 | PCI_PROBE_CONF2)) 
-		&& (pci_root_ops = pci_check_direct())) {
+		&& (tmp = pci_check_direct())) {
+		pci_root_ops = tmp;
 		if (pci_root_ops == &pci_direct_conf1) {
 			pci_config_read = pci_conf1_read;
 			pci_config_write = pci_conf1_write;
@@ -1393,11 +1479,11 @@
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	int err;
 
-	if ((err = pcibios_enable_resources(dev)) < 0)
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
 	pcibios_enable_irq(dev);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/pci-visws.c linux-bk/arch/i386/kernel/pci-visws.c
--- linux-2.4.19/arch/i386/kernel/pci-visws.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-bk/arch/i386/kernel/pci-visws.c	2002-11-22 15:35:25.000000000 +0000
@@ -131,9 +131,9 @@
 	return str;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
-	return pcibios_enable_resources(dev);
+	return pcibios_enable_resources(dev, mask);
 }
 
 void __init pcibios_penalize_isa_irq(irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/semaphore.c linux-bk/arch/i386/kernel/semaphore.c
--- linux-2.4.19/arch/i386/kernel/semaphore.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/semaphore.c	2002-11-22 15:35:29.000000000 +0000
@@ -262,31 +262,30 @@
  */
 #if defined(CONFIG_SMP)
 asm(
-"
-.align	4
-.globl	__write_lock_failed
-__write_lock_failed:
-	" LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)
-1:	rep; nop
-	cmpl	$" RW_LOCK_BIAS_STR ",(%eax)
-	jne	1b
-
-	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)
-	jnz	__write_lock_failed
-	ret
-
-
-.align	4
-.globl	__read_lock_failed
-__read_lock_failed:
-	lock ; incl	(%eax)
-1:	rep; nop
-	cmpl	$1,(%eax)
-	js	1b
+".text\n"
+".align	4\n"
+".globl	__write_lock_failed\n"
+"__write_lock_failed:\n\t"
+	LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)\n"
+"1:	rep; nop\n\t"
+	"cmpl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+	"jne	1b\n\t"
+	LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+	"jnz	__write_lock_failed\n\t"
+	"ret"
+);
 
-	lock ; decl	(%eax)
-	js	__read_lock_failed
-	ret
-"
+asm(
+".text\n"
+".align	4\n"
+".globl	__read_lock_failed\n"
+"__read_lock_failed:\n\t"
+	LOCK "incl	(%eax)\n"
+"1:	rep; nop\n\t"
+	"cmpl	$1,(%eax)\n\t"
+	"js	1b\n\t"
+	LOCK "decl	(%eax)\n\t"
+	"js	__read_lock_failed\n\t"
+	"ret"
 );
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/setup.c linux-bk/arch/i386/kernel/setup.c
--- linux-2.4.19/arch/i386/kernel/setup.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/setup.c	2002-11-22 15:35:30.000000000 +0000
@@ -71,13 +71,6 @@
  *  CacheSize bug workaround updates for AMD, Intel & VIA Cyrix.
  *  Dave Jones <davej@suse.de>, September, October 2001.
  *
- *  Short-term fix for a conflicting cache attribute bug in the kernel
- *  that is exposed by advanced speculative caching on new AMD Athlon
- *  processors.
- *  Richard Brunner <richard.brunner@amd.com> and Mark Langsdorf
- *  <mark.langsdorf@amd.com>, June 2002 
- *  Adapted to work with uniprocessor APIC by Bryan O'Sullivan
- *  <bos@serpentine.com>, June 2002.
  */
 
 /*
@@ -171,18 +164,15 @@
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 
+static int have_cpuid_p(void) __init;
+
 static int disable_x86_serial_nr __initdata = 1;
-static int disable_x86_fxsr __initdata = 0;
 static int disable_x86_ht __initdata = 0;
+static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 };
+extern int blk_nohighio;
 
 int enable_acpi_smp_table;
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-int disable_adv_spec_cache __initdata = 1;
-#else
-int disable_adv_spec_cache __initdata = 0;
-#endif /* CONFIG_AGP */
-
 /*
  * This is set up by the setup-routine at boot-time
  */
@@ -741,41 +731,6 @@
 } /* setup_memory_region */
 
 
-int __init amd_adv_spec_cache_feature(void)
-{
-	char vendor_id[16];
-	int ident;
-	int family, model;
- 
-	/* Must have CPUID */
-	if(!have_cpuid_p())
-		goto donthave;
-	if(cpuid_eax(0)<1)
-		goto donthave;
-	
-	/* Must be x86 architecture */
-	cpuid(0, &ident,  
-		(int *)&vendor_id[0],
-		(int *)&vendor_id[8],
-		(int *)&vendor_id[4]);
-
-	if (memcmp(vendor_id, "AuthenticAMD", 12)) 
-	       goto donthave;
-
-	ident = cpuid_eax(1);
-	family = (ident >> 8) & 0xf;
-	model  = (ident >> 4) & 0xf;
-	if (((family == 6)  && (model >= 6)) || (family == 15)) {
-		printk(KERN_INFO "Advanced speculative caching feature present\n");
-		return 1;
-	}
-
-donthave:
-	printk(KERN_INFO "Advanced speculative caching feature not present\n");
-	return 0;
-}
-
-
 static void __init parse_cmdline_early (char ** cmdline_p)
 {
 	char c = ' ', *to = command_line, *from = COMMAND_LINE;
@@ -802,6 +757,7 @@
 			if (!memcmp(from+4, "nopentium", 9)) {
 				from += 9+4;
 				clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
+				set_bit(X86_FEATURE_PSE, &disabled_x86_caps);
 			} else if (!memcmp(from+4, "exactmap", 8)) {
 				from += 8+4;
 				e820.nr_map = 0;
@@ -827,8 +783,10 @@
 		}
 
 		/* "noht" disables HyperThreading (2 logical cpus per Xeon) */
-		else if (!memcmp(from, "noht", 4))
+		else if (!memcmp(from, "noht", 4)) { 
 			disable_x86_ht = 1;
+			set_bit(X86_FEATURE_HT, disabled_x86_caps);
+		}
 
 		/* "acpismp=force" forces parsing and use of the ACPI SMP table */
 		else if (!memcmp(from, "acpismp=force", 13))
@@ -841,17 +799,6 @@
 		 */
 		else if (!memcmp(from, "highmem=", 8))
 			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
-		/*
-		 * unsafe-gart-alias overrides the short-term fix for a
-		 * conflicting cache attribute bug in the kernel that is
-		 * exposed by advanced speculative caching in newer AMD
-		 * Athlon processors.  Overriding the fix will allow
-		 * higher performance but the kernel bug can cause system
-		 * lock-ups if the system uses an AGP card.  unsafe-gart-alias
-		 * can be turned on for higher performance in servers.
-		 */
-		else if (!memcmp(from, "unsafe-gart-alias", 17))
-			disable_adv_spec_cache = 0;
 nextchar:
 		c = *(from++);
 		if (!c)
@@ -868,49 +815,6 @@
 	}
 }
 
-void __init setup_arch(char **cmdline_p)
-{
-	unsigned long bootmap_size, low_mem_size;
-	unsigned long start_pfn, max_pfn, max_low_pfn;
-	int i;
-
-#ifdef CONFIG_VISWS
-	visws_get_board_type_and_rev();
-#endif
-
- 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
- 	drive_info = DRIVE_INFO;
- 	screen_info = SCREEN_INFO;
-	apm_info.bios = APM_BIOS_INFO;
-	if( SYS_DESC_TABLE.length != 0 ) {
-		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
-		machine_id = SYS_DESC_TABLE.table[0];
-		machine_submodel_id = SYS_DESC_TABLE.table[1];
-		BIOS_revision = SYS_DESC_TABLE.table[2];
-	}
-	aux_device_present = AUX_DEVICE_INFO;
-
-#ifdef CONFIG_BLK_DEV_RAM
-	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
-	setup_memory_region();
-
-	if (!MOUNT_ROOT_RDONLY)
-		root_mountflags &= ~MS_RDONLY;
-	init_mm.start_code = (unsigned long) &_text;
-	init_mm.end_code = (unsigned long) &_etext;
-	init_mm.end_data = (unsigned long) &_edata;
-	init_mm.brk = (unsigned long) &_end;
-
-	code_resource.start = virt_to_bus(&_text);
-	code_resource.end = virt_to_bus(&_etext)-1;
-	data_resource.start = virt_to_bus(&_etext);
-	data_resource.end = virt_to_bus(&_edata)-1;
-
-	parse_cmdline_early(cmdline_p);
-
 #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
@@ -921,15 +825,13 @@
 #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
 #define MAX_NONPAE_PFN	(1 << 20)
 
-	/*
-	 * partially used pages are not usable - thus
-	 * we are rounding upwards:
-	 */
-	start_pfn = PFN_UP(__pa(&_end));
+/*
+ * Find the highest page frame number we have available
+ */
+static void __init find_max_pfn(void)
+{
+	int i;
 
-	/*
-	 * Find the highest page frame number we have available
-	 */
 	max_pfn = 0;
 	for (i = 0; i < e820.nr_map; i++) {
 		unsigned long start, end;
@@ -943,10 +845,15 @@
 		if (end > max_pfn)
 			max_pfn = end;
 	}
+}
+
+/*
+ * Determine low and high memory ranges:
+ */
+static unsigned long __init find_max_low_pfn(void)
+{
+	unsigned long max_low_pfn;
 
-	/*
-	 * Determine low and high memory ranges:
-	 */
 	max_low_pfn = max_pfn;
 	if (max_low_pfn > MAXMEM_PFN) {
 		if (highmem_pages == -1)
@@ -996,27 +903,19 @@
 #endif
 	}
 
-#ifdef CONFIG_HIGHMEM
-	highstart_pfn = highend_pfn = max_pfn;
-	if (max_pfn > max_low_pfn) {
-		highstart_pfn = max_low_pfn;
-	}
-	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-		pages_to_mb(highend_pfn - highstart_pfn));
-#endif
-	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
-			pages_to_mb(max_low_pfn));
-	/*
-	 * Initialize the boot-time allocator (with low memory only):
-	 */
-	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+	return max_low_pfn;
+}
+
+/*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
+{
+	int i;
 
-	/*
-	 * Register fully available low RAM pages with the bootmem allocator.
-	 */
 	for (i = 0; i < e820.nr_map; i++) {
 		unsigned long curr_pfn, last_pfn, size;
- 		/*
+		/*
 		 * Reserve usable low memory
 		 */
 		if (e820.map[i].type != E820_RAM)
@@ -1045,6 +944,39 @@
 		size = last_pfn - curr_pfn;
 		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
 	}
+}
+
+static unsigned long __init setup_memory(void)
+{
+	unsigned long bootmap_size, start_pfn, max_low_pfn;
+
+	/*
+	 * partially used pages are not usable - thus
+	 * we are rounding upwards:
+	 */
+	start_pfn = PFN_UP(__pa(&_end));
+
+	find_max_pfn();
+
+	max_low_pfn = find_max_low_pfn();
+
+#ifdef CONFIG_HIGHMEM
+	highstart_pfn = highend_pfn = max_pfn;
+	if (max_pfn > max_low_pfn) {
+		highstart_pfn = max_low_pfn;
+	}
+	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+		pages_to_mb(highend_pfn - highstart_pfn));
+#endif
+	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
+			pages_to_mb(max_low_pfn));
+	/*
+	 * Initialize the boot-time allocator (with low memory only):
+	 */
+	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+
+	register_bootmem_low_pages(max_low_pfn);
+
 	/*
 	 * Reserve the bootmem bitmap itself as well. We do this in two
 	 * steps (first step was init_bootmem()) because this catches
@@ -1093,51 +1025,18 @@
 	}
 #endif
 
-	/*
-	 * If enable_acpi_smp_table and HT feature present, acpitable.c
-	 * will find all logical cpus despite disable_x86_ht: so if both
-	 * "noht" and "acpismp=force" are specified, let "noht" override
-	 * "acpismp=force" cleanly.  Why retain "acpismp=force"? because
-	 * parsing ACPI SMP table might prove useful on some non-HT cpu.
-	 */
-	if (disable_x86_ht) {
-		clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]);
-		enable_acpi_smp_table = 0;
-	}
-	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
-		enable_acpi_smp_table = 1;
-	
-
-	/*
-	 * NOTE: before this point _nobody_ is allowed to allocate
-	 * any memory using the bootmem allocator.
-	 */
-
-#ifdef CONFIG_SMP
-	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
-#endif
-	/*
-	 * short-term fix for a conflicting cache attribute bug in the 
-	 * kernel that is exposed by advanced speculative caching on
-	 * newer AMD Athlon processors.
-	 */
-	if (disable_adv_spec_cache && amd_adv_spec_cache_feature())
-		clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
-
-	paging_init();
-#ifdef CONFIG_X86_LOCAL_APIC
-	/*
-	 * get boot-time SMP configuration:
-	 */
-	if (smp_found_config)
-		get_smp_config();
-#endif
-
+	return max_low_pfn;
+}
+ 
+/*
+ * Request address space for all standard RAM and ROM resources
+ * and also for regions reported as reserved by the e820.
+ */
+static void __init register_memory(unsigned long max_low_pfn)
+{
+	unsigned long low_mem_size;
+	int i;
 
-	/*
-	 * Request address space for all standard RAM and ROM resources
-	 * and also for regions reported as reserved by the e820.
-	 */
 	probe_roms();
 	for (i = 0; i < e820.nr_map; i++) {
 		struct resource *res;
@@ -1174,6 +1073,89 @@
 	low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
 	if (low_mem_size > pci_mem_start)
 		pci_mem_start = low_mem_size;
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	unsigned long max_low_pfn;
+
+#ifdef CONFIG_VISWS
+	visws_get_board_type_and_rev();
+#endif
+
+#ifndef CONFIG_HIGHIO
+	blk_nohighio = 1;
+#endif
+
+ 	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
+ 	drive_info = DRIVE_INFO;
+ 	screen_info = SCREEN_INFO;
+	apm_info.bios = APM_BIOS_INFO;
+	if( SYS_DESC_TABLE.length != 0 ) {
+		MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
+		machine_id = SYS_DESC_TABLE.table[0];
+		machine_submodel_id = SYS_DESC_TABLE.table[1];
+		BIOS_revision = SYS_DESC_TABLE.table[2];
+	}
+	aux_device_present = AUX_DEVICE_INFO;
+
+#ifdef CONFIG_BLK_DEV_RAM
+	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
+	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+#endif
+	setup_memory_region();
+
+	if (!MOUNT_ROOT_RDONLY)
+		root_mountflags &= ~MS_RDONLY;
+	init_mm.start_code = (unsigned long) &_text;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) &_end;
+
+	code_resource.start = virt_to_bus(&_text);
+	code_resource.end = virt_to_bus(&_etext)-1;
+	data_resource.start = virt_to_bus(&_etext);
+	data_resource.end = virt_to_bus(&_edata)-1;
+
+	parse_cmdline_early(cmdline_p);
+
+	max_low_pfn = setup_memory();
+
+	/*
+	 * If enable_acpi_smp_table and HT feature present, acpitable.c
+	 * will find all logical cpus despite disable_x86_ht: so if both
+	 * "noht" and "acpismp=force" are specified, let "noht" override
+	 * "acpismp=force" cleanly.  Why retain "acpismp=force"? because
+	 * parsing ACPI SMP table might prove useful on some non-HT cpu.
+	 */
+	if (disable_x86_ht) {
+		clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]);
+		set_bit(X86_FEATURE_HT, disabled_x86_caps);
+		enable_acpi_smp_table = 0;
+	}
+	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
+		enable_acpi_smp_table = 1;
+	
+
+	/*
+	 * NOTE: before this point _nobody_ is allowed to allocate
+	 * any memory using the bootmem allocator.
+	 */
+
+#ifdef CONFIG_SMP
+	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+#endif
+	paging_init();
+#ifdef CONFIG_X86_LOCAL_APIC
+	/*
+	 * get boot-time SMP configuration:
+	 */
+	if (smp_found_config)
+		get_smp_config();
+#endif
+
+	register_memory(max_low_pfn);
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
@@ -1197,14 +1179,27 @@
 #ifndef CONFIG_X86_TSC
 static int tsc_disable __initdata = 0;
 
-static int __init tsc_setup(char *str)
+static int __init notsc_setup(char *str)
 {
 	tsc_disable = 1;
 	return 1;
 }
-
-__setup("notsc", tsc_setup);
+#else
+static int __init notsc_setup(char *str)
+{
+	printk("notsc: Kernel compiled with CONFIG_X86_TSC, cannot disable TSC.\n");
+	return 1;
+}
 #endif
+__setup("notsc", notsc_setup);
+
+static int __init highio_setup(char *str)
+{
+	printk("i386: disabling HIGHMEM block I/O\n");
+	blk_nohighio = 1;
+	return 1;
+}
+__setup("nohighio", highio_setup);
 
 static int __init get_model_name(struct cpuinfo_x86 *c)
 {
@@ -1292,31 +1287,6 @@
 	       l2size, ecx & 0xFF);
 }
 
-
-/*=======================================================================
- * amd_adv_spec_cache_disable
- * Setting a special MSR big that disables a small part of advanced
- * speculative caching as part of a short-term fix for a conflicting cache
- * attribute bug in the kernel that is exposed by advanced speculative
- * caching in newer AMD Athlon processors.
- =======================================================================*/
-static void amd_adv_spec_cache_disable(void)
-{
-	printk(KERN_INFO "Disabling advanced speculative caching\n");
-
-	__asm__ __volatile__ (
-		" movl	 $0x9c5a203a,%%edi   \n" /* msr enable */
-		" movl	 $0xc0011022,%%ecx   \n" /* msr addr	 */
-		" rdmsr			     \n" /* get reg val	 */
-		" orl	 $0x00010000,%%eax   \n" /* set bit 16	 */
-		" wrmsr			     \n" /* put it back	 */
-		" xorl	%%edi, %%edi	     \n" /* clear msr enable */
-		: /* no outputs */
-		: /* no inputs, either */
-		: "%eax","%ecx","%edx","%edi" /* clobbered regs */ );
-}
-
-
 /*
  *	B step AMD K6 before B 9730xxxx have hardware bugs that can cause
  *	misexecution of code under Linux. Owners of such processors should
@@ -1450,21 +1420,10 @@
  			 * to enable SSE on Palomino/Morgan CPU's.
 			 * If the BIOS didn't enable it already, enable it
 			 * here.
-			 *
-			 * Avoiding the use of 4MB/2MB pages along with
-			 * setting a special MSR bit that disables a small
-			 * part of advanced speculative caching as part of a
-			 * short-term fix for a conflicting cache attribute
-			 * bug in the kernel that is exposed by advanced
-			 * speculative caching in newer AMD Atlon processors.
-			 *
-			 * If we cleared the PSE bit earlier as part
-			 * of the workaround for this problem, we need
-			 * to clear it again, as our caller may have
-			 * clobbered it if uniprocessor APIC is enabled.
 			 */
-			if (c->x86_model >= 6) {
-				if (!cpu_has_xmm) {
+			if (c->x86_model == 6 || c->x86_model == 7) {
+				if (!test_bit(X86_FEATURE_XMM,
+					      &c->x86_capability)) {
 					printk(KERN_INFO
 					       "Enabling Disabled K7/SSE Support...\n");
 					rdmsr(MSR_K7_HWCR, l, h);
@@ -1473,18 +1432,6 @@
 					set_bit(X86_FEATURE_XMM,
                                                 &c->x86_capability);
 				}
-				if (disable_adv_spec_cache &&
-				    amd_adv_spec_cache_feature()) {
-					clear_bit(X86_FEATURE_PSE,
-						  &c->x86_capability);
-					amd_adv_spec_cache_disable();
-				}
-			}
-			break;
-		case 15: 
-			if (disable_adv_spec_cache && amd_adv_spec_cache_feature()) {
-				clear_bit(X86_FEATURE_PSE, &c->x86_capability);
-				amd_adv_spec_cache_disable();
 			}
 			break;
 
@@ -1534,7 +1481,7 @@
  * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in
  * order to identify the Cyrix CPU model after we're out of setup.c
  *
- * Actually since bugs.h doesnt even reference this perhaps someone should
+ * Actually since bugs.h doesn't even reference this perhaps someone should
  * fix the documentation ???
  */
 static unsigned char Cx86_dir0_msb __initdata = 0;
@@ -2198,6 +2145,11 @@
 	wrmsr(0x80860004, ~0, uk);
 	c->x86_capability[0] = cpuid_edx(0x00000001);
 	wrmsr(0x80860004, cap_mask, uk);
+
+	/* If we can run i686 user-space code, call us an i686 */
+#define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV)
+	if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 )
+	     c->x86 = 6;
 }
 
 
@@ -2227,31 +2179,69 @@
 
 extern void trap_init_f00f_bug(void);
 
+#define LVL_1_INST      1
+#define LVL_1_DATA      2
+#define LVL_2           3
+#define LVL_3           4
+
+struct _cache_table
+{
+        unsigned char descriptor;
+        char cache_type;
+        short size;
+};
+
+/* all the cache descriptor types we care about (no TLB or trace cache entries) */
+static struct _cache_table cache_table[] __initdata =
+{
+	{ 0x06, LVL_1_INST, 8 },
+	{ 0x08, LVL_1_INST, 16 },
+	{ 0x0A, LVL_1_DATA, 8 },
+	{ 0x0C, LVL_1_DATA, 16 },
+	{ 0x22, LVL_3,      512 },
+	{ 0x23, LVL_3,      1024 },
+	{ 0x25, LVL_3,      2048 },
+	{ 0x29, LVL_3,      4096 },
+	{ 0x41, LVL_2,      128 },
+	{ 0x42, LVL_2,      256 },
+	{ 0x43, LVL_2,      512 },
+	{ 0x44, LVL_2,      1024 },
+	{ 0x45, LVL_2,      2048 },
+	{ 0x66, LVL_1_DATA, 8 },
+	{ 0x67, LVL_1_DATA, 16 },
+	{ 0x68, LVL_1_DATA, 32 },
+	{ 0x79, LVL_2,      128 },
+	{ 0x7A, LVL_2,      256 },
+	{ 0x7B, LVL_2,      512 },
+	{ 0x7C, LVL_2,      1024 },
+	{ 0x82, LVL_2,      256 },
+	{ 0x84, LVL_2,      1024 },
+	{ 0x85, LVL_2,      2048 },
+	{ 0x00, 0, 0}
+};
+
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
-#ifndef CONFIG_M686
-	static int f00f_workaround_enabled = 0;
-#endif
-	char *p = NULL;
 	unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+	char *p = NULL;
+#ifndef CONFIG_X86_F00F_WORKS_OK
+	static int f00f_workaround_enabled = 0;
 
-#ifndef CONFIG_M686
 	/*
 	 * All current models of Pentium and Pentium with MMX technology CPUs
 	 * have the F0 0F bug, which lets nonpriviledged users lock up the system.
 	 * Note that the workaround only should be initialized once...
 	 */
 	c->f00f_bug = 0;
-	if ( c->x86 == 5 ) {
+	if (c->x86 == 5) {
 		c->f00f_bug = 1;
-		if ( !f00f_workaround_enabled ) {
+		if (!f00f_workaround_enabled) {
 			trap_init_f00f_bug();
 			printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
 			f00f_workaround_enabled = 1;
 		}
 	}
-#endif
-
+#endif /* CONFIG_X86_F00F_WORKS_OK */
 
 	if (c->cpuid_level > 1) {
 		/* supports eax=2  call */
@@ -2273,83 +2263,31 @@
 			/* Byte 0 is level count, not a descriptor */
 			for ( j = 1 ; j < 16 ; j++ ) {
 				unsigned char des = dp[j];
-				unsigned char dl, dh;
-				unsigned int cs;
-
-				dh = des >> 4;
-				dl = des & 0x0F;
+				unsigned char k = 0;
 
-				/* Black magic... */
-
-				switch ( dh )
+				/* look up this descriptor in the table */
+				while (cache_table[k].descriptor != 0)
 				{
-				case 0:
-					switch ( dl ) {
-					case 6:
-						/* L1 I cache */
-						l1i += 8;
-						break;
-					case 8:
-						/* L1 I cache */
-						l1i += 16;
-						break;
-					case 10:
-						/* L1 D cache */
-						l1d += 8;
-						break;
-					case 12:
-						/* L1 D cache */
-						l1d += 16;
-						break;
-					default:;
-						/* TLB, or unknown */
-					}
-					break;
-				case 2:
-					if ( dl ) {
-						/* L3 cache */
-						cs = (dl-1) << 9;
-						l3 += cs;
-					}
-					break;
-				case 4:
-					if ( c->x86 > 6 && dl ) {
-						/* P4 family */
-						/* L3 cache */
-						cs = 128 << (dl-1);
-						l3 += cs;
+					if (cache_table[k].descriptor == des) {
+						switch (cache_table[k].cache_type) {
+						case LVL_1_INST:
+							l1i += cache_table[k].size;
+							break;
+						case LVL_1_DATA:
+							l1d += cache_table[k].size;
+							break;
+						case LVL_2:
+							l2 += cache_table[k].size;
+							break;
+						case LVL_3:
+							l3 += cache_table[k].size;
+							break;
+						}
+
 						break;
 					}
-					/* else same as 8 - fall through */
-				case 8:
-					if ( dl ) {
-						/* L2 cache */
-						cs = 128 << (dl-1);
-						l2 += cs;
-					}
-					break;
-				case 6:
-					if (dl > 5) {
-						/* L1 D cache */
-						cs = 8<<(dl-6);
-						l1d += cs;
-					}
-					break;
-				case 7:
-					if ( dl >= 8 ) 
-					{
-						/* L2 cache */
-						cs = 64<<(dl-8);
-						l2 += cs;
-					} else {
-						/* L0 I cache, count as L1 */
-						cs = dl ? (16 << (dl-1)) : 12;
-						l1i += cs;
-					}
-					break;
-				default:
-					/* TLB, or something else we don't know about */
-					break;
+
+					k++;
 				}
 			}
 		}
@@ -2426,7 +2364,7 @@
 			if (smp_num_siblings != NR_SIBLINGS) {
 				printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
 				smp_num_siblings = 1;
-				goto too_many_siblings;
+				return;
 			}
 			tmp = smp_num_siblings;
 			while ((tmp & 1) == 0) {
@@ -2448,7 +2386,6 @@
 		}
 
 	}
-too_many_siblings:
 #endif
 }
 
@@ -2596,7 +2533,8 @@
 
 static int __init x86_fxsr_setup(char * s)
 {
-	disable_x86_fxsr = 1;
+	set_bit(X86_FEATURE_XMM, disabled_x86_caps); 
+	set_bit(X86_FEATURE_FXSR, disabled_x86_caps);
 	return 1;
 }
 __setup("nofxsr", x86_fxsr_setup);
@@ -2749,12 +2687,6 @@
 			      &c->x86_capability[0]);
 			c->x86 = (tfms >> 8) & 15;
 			c->x86_model = (tfms >> 4) & 15;
-			if ( (c->x86_vendor == X86_VENDOR_AMD) &&
-				(c->x86 == 0xf)) {
-				/* AMD Extended Family and Model Values */
-				c->x86 += (tfms >> 20) & 0xff;
-				c->x86_model += (tfms >> 12) & 0xf0;
-			}
 			c->x86_mask = tfms & 15;
 		} else {
 			/* Have CPUID level 0 only - unheard of */
@@ -2778,12 +2710,6 @@
 		}
 	}
 
-	printk(KERN_DEBUG "CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n",
-	       c->x86_capability[0],
-	       c->x86_capability[1],
-	       c->x86_capability[2],
-	       c->x86_vendor);
-
 	/*
 	 * Vendor-specific initialization.  In this section we
 	 * canonicalize the feature flags, meaning if there are
@@ -2842,12 +2768,6 @@
 		break;
 	}
 
-	printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n",
-	       c->x86_capability[0],
-	       c->x86_capability[1],
-	       c->x86_capability[2],
-	       c->x86_capability[3]);
-
 	/*
 	 * The vendor-specific functions might have changed features.  Now
 	 * we do "generic changes."
@@ -2859,14 +2779,9 @@
 		clear_bit(X86_FEATURE_TSC, &c->x86_capability);
 #endif
 
-	/* HT disabled? */
-	if (disable_x86_ht)
-		clear_bit(X86_FEATURE_HT, &c->x86_capability);
-
-	/* FXSR disabled? */
-	if (disable_x86_fxsr) {
-		clear_bit(X86_FEATURE_FXSR, &c->x86_capability);
-		clear_bit(X86_FEATURE_XMM, &c->x86_capability);
+	/* check for caps that have been disabled earlier */ 
+	for (i = 0; i < NCAPINTS; i++) { 
+	     c->x86_capability[i] &= ~disabled_x86_caps[i];
 	}
 
 	/* Disable the PN if appropriate */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/smp.c linux-bk/arch/i386/kernel/smp.c
--- linux-2.4.19/arch/i386/kernel/smp.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/smp.c	2002-11-22 15:35:24.000000000 +0000
@@ -66,7 +66,7 @@
  *	an L1cache=Writethrough or L1cache=off option.
  *
  *		B stepping CPUs may hang. There are hardware work arounds
- *	for this. We warn about it in case your board doesnt have the work
+ *	for this. We warn about it in case your board doesn't have the work
  *	arounds. Basically thats so I can tell anyone with a B stepping
  *	CPU and SMP problems "tough".
  *
@@ -115,7 +115,7 @@
 
 static inline int __prepare_ICR (unsigned int shortcut, int vector)
 {
-	return APIC_DM_FIXED | shortcut | vector | APIC_DEST_LOGICAL;
+	return APIC_DM_FIXED | shortcut | vector | INT_DEST_ADDR_MODE;
 }
 
 static inline int __prepare_ICR2 (unsigned int mask)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/smpboot.c linux-bk/arch/i386/kernel/smpboot.c
--- linux-2.4.19/arch/i386/kernel/smpboot.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/smpboot.c	2002-11-22 15:35:30.000000000 +0000
@@ -830,7 +830,7 @@
 
 	Dprintk("Setting warm reset code and vector.\n");
 
-	if (clustered_apic_mode) {
+	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
 		/* stash the current NMI vector, so we can put things back */
 		nmi_high = *((volatile unsigned short *) TRAMPOLINE_HIGH);
 		nmi_low = *((volatile unsigned short *) TRAMPOLINE_LOW);
@@ -862,7 +862,7 @@
 	 * Starting actual IPI sequence...
 	 */
 
-	if (clustered_apic_mode)
+	if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
 		boot_error = wakeup_secondary_via_NMI(apicid);
 	else 
 		boot_error = wakeup_secondary_via_INIT(apicid, start_eip);
@@ -917,7 +917,7 @@
 	/* mark "stuck" area as not stuck */
 	*((volatile unsigned long *)phys_to_virt(8192)) = 0;
 
-	if(clustered_apic_mode) {
+	if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
 		printk("Restoring NMI vector\n");
 		*((volatile unsigned short *) TRAMPOLINE_HIGH) = nmi_high;
 		*((volatile unsigned short *) TRAMPOLINE_LOW) = nmi_low;
@@ -981,7 +981,7 @@
 {
 	int apicid, cpu, bit;
 
-        if (clustered_apic_mode && (numnodes > 1)) {
+        if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && (numnodes > 1)) {
                 printk("Remapping cross-quad port I/O for %d quads\n",
 			numnodes);
                 printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/time.c linux-bk/arch/i386/kernel/time.c
--- linux-2.4.19/arch/i386/kernel/time.c	2002-02-25 19:37:53.000000000 +0000
+++ linux-bk/arch/i386/kernel/time.c	2002-11-22 15:35:30.000000000 +0000
@@ -31,6 +31,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
@@ -116,6 +117,8 @@
 
 spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
 
+EXPORT_SYMBOL(i8253_lock);
+
 extern spinlock_t i8259A_lock;
 
 #ifndef CONFIG_X86_TSC
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/trampoline.S linux-bk/arch/i386/kernel/trampoline.S
--- linux-2.4.19/arch/i386/kernel/trampoline.S	2001-10-05 01:42:54.000000000 +0000
+++ linux-bk/arch/i386/kernel/trampoline.S	2002-11-22 15:35:28.000000000 +0000
@@ -36,9 +36,7 @@
 
 ENTRY(trampoline_data)
 r_base = .
-#ifdef CONFIG_MULTIQUAD
-	wbinvd
-#endif /* CONFIG_MULTIQUAD */
+	wbinvd			# Needed for NUMA-Q should be harmless for others
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/kernel/traps.c linux-bk/arch/i386/kernel/traps.c
--- linux-2.4.19/arch/i386/kernel/traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/kernel/traps.c	2002-11-22 15:35:25.000000000 +0000
@@ -40,9 +40,9 @@
 
 #include <asm/smp.h>
 #include <asm/pgalloc.h>
+#include <asm/fixmap.h>
 
 #ifdef CONFIG_X86_VISWS_APIC
-#include <asm/fixmap.h>
 #include <asm/cobalt.h>
 #include <asm/lithium.h>
 #endif
@@ -186,6 +186,14 @@
 	show_trace(esp);
 }
 
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
 void show_registers(struct pt_regs *regs)
 {
 	int i;
@@ -305,8 +313,13 @@
 static void inline do_trap(int trapnr, int signr, char *str, int vm86,
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
-	if (vm86 && regs->eflags & VM_MASK)
-		goto vm86_trap;
+	if (regs->eflags & VM_MASK) {
+		if (vm86)
+			goto vm86_trap;
+		else
+			goto trap_signal;
+	}
+
 	if (!(regs->xcs & 3))
 		goto kernel_trap;
 
@@ -514,10 +527,15 @@
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
+	unsigned long eip = regs->eip;
 	siginfo_t info;
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+	/* If the user set TF, it's simplest to clear it right away. */
+	if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
+		goto clear_TF;
+
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7])
@@ -758,35 +776,17 @@
 
 #endif /* CONFIG_MATH_EMULATION */
 
-#ifndef CONFIG_M686
+#ifndef CONFIG_X86_F00F_WORKS_OK
 void __init trap_init_f00f_bug(void)
 {
-	unsigned long page;
-	pgd_t * pgd;
-	pmd_t * pmd;
-	pte_t * pte;
-
-	/*
-	 * Allocate a new page in virtual address space, 
-	 * move the IDT into it and write protect this page.
-	 */
-	page = (unsigned long) vmalloc(PAGE_SIZE);
-	pgd = pgd_offset(&init_mm, page);
-	pmd = pmd_offset(pgd, page);
-	pte = pte_offset(pmd, page);
-	__free_page(pte_page(*pte));
-	*pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO);
-	/*
-	 * Not that any PGE-capable kernel should have the f00f bug ...
-	 */
-	__flush_tlb_all();
-
 	/*
 	 * "idt" is magic - it overlaps the idt_descr
 	 * variable so that updating idt will automatically
 	 * update the idt descriptor..
 	 */
-	idt = (struct desc_struct *)page;
+	__set_fixmap(FIX_F00F, __pa(&idt_table), PAGE_KERNEL_RO);
+	idt = (struct desc_struct *)__fix_to_virt(FIX_F00F);
+
 	__asm__ __volatile__("lidt %0": "=m" (idt_descr));
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/lib/checksum.S linux-bk/arch/i386/lib/checksum.S
--- linux-2.4.19/arch/i386/lib/checksum.S	2000-09-05 21:01:35.000000000 +0000
+++ linux-bk/arch/i386/lib/checksum.S	2002-11-22 15:35:26.000000000 +0000
@@ -55,8 +55,21 @@
 	movl 20(%esp),%eax	# Function arg: unsigned int sum
 	movl 16(%esp),%ecx	# Function arg: int len
 	movl 12(%esp),%esi	# Function arg: unsigned char *buff
-	testl $2, %esi		# Check alignment.
+	testl $3, %esi		# Check alignment.
 	jz 2f			# Jump if alignment is ok.
+	testl $1, %esi		# Check alignment.
+	jz 10f			# Jump if alignment is boundary of 2bytes.
+
+	# buf is odd
+	dec %ecx
+	jl 8f
+	movzbl (%esi), %ebx
+	adcl %ebx, %eax
+	roll $8, %eax
+	inc %esi
+	testl $2, %esi
+	jz 2f
+10:
 	subl $2, %ecx		# Alignment uses up two bytes.
 	jae 1f			# Jump if we had at least two bytes.
 	addl $2, %ecx		# ecx was < 2.  Deal with it.
@@ -111,6 +124,10 @@
 6:	addl %ecx,%eax
 	adcl $0, %eax 
 7:	
+	testl $1, 12(%esp)
+	jz 8f
+	roll $8, %eax
+8:
 	popl %ebx
 	popl %esi
 	ret
@@ -126,8 +143,8 @@
 	movl 16(%esp),%ecx	# Function arg: int len
 	movl 12(%esp),%esi	# Function arg:	const unsigned char *buf
 
-	testl $2, %esi         
-	jnz 30f                 
+	testl $3, %esi         
+	jnz 25f                 
 10:
 	movl %ecx, %edx
 	movl %ecx, %ebx
@@ -145,10 +162,25 @@
 	lea 2(%esi), %esi
 	adcl $0, %eax
 	jmp 10b
+25:
+	testl $1, %esi         
+	jz 30f                 
+	# buf is odd
+	dec %ecx
+	jl 90f
+	movzbl (%esi), %ebx
+	addl %ebx, %eax
+	adcl $0, %eax
+	roll $8, %eax
+	inc %esi
+	testl $2, %esi
+	jz 10b
 
 30:	subl $2, %ecx          
 	ja 20b                 
 	je 32f
+	addl $2, %ecx
+	jz 80f
 	movzbl (%esi),%ebx	# csumming 1 byte, 2-aligned
 	addl %ebx, %eax
 	adcl $0, %eax
@@ -209,6 +241,10 @@
 	addl %ebx,%eax
 	adcl $0,%eax
 80: 
+	testl $1, 12(%esp)
+	jz 90f
+	roll $8, %eax
+90: 
 	popl %ebx
 	popl %esi
 	ret
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/Makefile linux-bk/arch/i386/mm/Makefile
--- linux-2.4.19/arch/i386/mm/Makefile	2000-12-29 22:07:20.000000000 +0000
+++ linux-bk/arch/i386/mm/Makefile	2002-11-22 15:35:26.000000000 +0000
@@ -9,6 +9,7 @@
 
 O_TARGET := mm.o
 
-obj-y	 := init.o fault.o ioremap.o extable.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
+export-objs := pageattr.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/fault.c linux-bk/arch/i386/mm/fault.c
--- linux-2.4.19/arch/i386/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/mm/fault.c	2002-11-22 15:35:22.000000000 +0000
@@ -86,8 +86,7 @@
 
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		goto survive;
 	}
 	goto bad_area;
@@ -334,13 +333,11 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (error_code & 4)
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/init.c linux-bk/arch/i386/mm/init.c
--- linux-2.4.19/arch/i386/mm/init.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/i386/mm/init.c	2002-11-22 15:35:25.000000000 +0000
@@ -320,6 +320,27 @@
 	flush_tlb_all();
 }
 
+static void __init zone_sizes_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+	unsigned int max_dma, high, low;
+
+	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+	low = max_low_pfn;
+	high = highend_pfn;
+
+	if (low < max_dma)
+		zones_size[ZONE_DMA] = low;
+	else {
+		zones_size[ZONE_DMA] = max_dma;
+		zones_size[ZONE_NORMAL] = low - max_dma;
+#ifdef CONFIG_HIGHMEM
+		zones_size[ZONE_HIGHMEM] = high - low;
+#endif
+	}
+	free_area_init(zones_size);
+}
+
 /*
  * paging_init() sets up the page tables - note that the first 8MB are
  * already mapped by head.S.
@@ -347,26 +368,7 @@
 #ifdef CONFIG_HIGHMEM
 	kmap_init();
 #endif
-	{
-		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-		unsigned int max_dma, high, low;
-
-		max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-		low = max_low_pfn;
-		high = highend_pfn;
-
-		if (low < max_dma)
-			zones_size[ZONE_DMA] = low;
-		else {
-			zones_size[ZONE_DMA] = max_dma;
-			zones_size[ZONE_NORMAL] = low - max_dma;
-#ifdef CONFIG_HIGHMEM
-			zones_size[ZONE_HIGHMEM] = high - low;
-#endif
-		}
-		free_area_init(zones_size);
-	}
-	return;
+	zone_sizes_init();
 }
 
 /*
@@ -443,62 +445,81 @@
 		return 1;
 	return 0;
 }
-	
-void __init mem_init(void)
-{
-	extern int ppro_with_ram_bug(void);
-	int codesize, reservedpages, datasize, initsize;
-	int tmp;
-	int bad_ppro;
 
-	if (!mem_map)
-		BUG();
+#ifdef CONFIG_HIGHMEM
+void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+{
+	if (!page_is_ram(pfn)) {
+		SetPageReserved(page);
+		return;
+	}
 	
-	bad_ppro = ppro_with_ram_bug();
+	if (bad_ppro && page_kills_ppro(pfn)) {
+		SetPageReserved(page);
+		return;
+	}
+	
+	ClearPageReserved(page);
+	set_bit(PG_highmem, &page->flags);
+	atomic_set(&page->count, 1);
+	__free_page(page);
+	totalhigh_pages++;
+}
+#endif /* CONFIG_HIGHMEM */
 
+static void __init set_max_mapnr_init(void)
+{
 #ifdef CONFIG_HIGHMEM
-	highmem_start_page = mem_map + highstart_pfn;
-	max_mapnr = num_physpages = highend_pfn;
-	num_mappedpages = max_low_pfn;
+        highmem_start_page = mem_map + highstart_pfn;
+        max_mapnr = num_physpages = highend_pfn;
+        num_mappedpages = max_low_pfn;
 #else
-	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+        max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
 #endif
-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+}
 
-	/* clear the zero-page */
-	memset(empty_zero_page, 0, PAGE_SIZE);
+static int __init free_pages_init(void)
+{
+	extern int ppro_with_ram_bug(void);
+	int bad_ppro, reservedpages, pfn;
+
+	bad_ppro = ppro_with_ram_bug();
 
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem();
 
 	reservedpages = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
+	for (pfn = 0; pfn < max_low_pfn; pfn++) {
 		/*
 		 * Only count reserved RAM pages
 		 */
-		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+		if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
 			reservedpages++;
-#ifdef CONFIG_HIGHMEM
-	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
-		struct page *page = mem_map + tmp;
-
-		if (!page_is_ram(tmp)) {
-			SetPageReserved(page);
-			continue;
-		}
-		if (bad_ppro && page_kills_ppro(tmp))
-		{
-			SetPageReserved(page);
-			continue;
-		}
-		ClearPageReserved(page);
-		set_bit(PG_highmem, &page->flags);
-		atomic_set(&page->count, 1);
-		__free_page(page);
-		totalhigh_pages++;
 	}
+#ifdef CONFIG_HIGHMEM
+	for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
+		one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
 	totalram_pages += totalhigh_pages;
 #endif
+	return reservedpages;
+}
+
+void __init mem_init(void)
+{
+	int codesize, reservedpages, datasize, initsize;
+
+	if (!mem_map)
+		BUG();
+	
+	set_max_mapnr_init();
+
+	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+
+	/* clear the zero-page */
+	memset(empty_zero_page, 0, PAGE_SIZE);
+
+	reservedpages = free_pages_init();
+
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/i386/mm/pageattr.c linux-bk/arch/i386/mm/pageattr.c
--- linux-2.4.19/arch/i386/mm/pageattr.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/i386/mm/pageattr.c	2002-11-22 15:35:27.000000000 +0000
@@ -0,0 +1,175 @@
+/* 
+ * Copyright 2002 Andi Kleen, SuSE Labs. 
+ * Thanks to Ben LaHaise for precious feedback.
+ */ 
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+
+/* Should move most of this stuff into the appropiate includes */
+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+
+static inline pte_t *lookup_address(unsigned long address) 
+{ 
+	pmd_t *pmd;	
+	pgd_t *pgd = pgd_offset(&init_mm, address); 
+
+	if (pgd_none(*pgd))
+		return NULL; 
+	if (pgd_val(*pgd) & _PAGE_PSE)
+		return (pte_t *)pgd; 
+	pmd = pmd_offset(pgd, address); 	       
+	if (pmd_none(*pmd))
+		return NULL; 
+	if (pmd_val(*pmd) & _PAGE_PSE) 
+		return (pte_t *)pmd; 
+    return pte_offset(pmd, address);
+} 
+
+static struct page *split_large_page(unsigned long address, pgprot_t prot)
+{ 
+	int i; 
+	unsigned long addr;
+	struct page *base = alloc_pages(GFP_KERNEL, 0);
+	pte_t *pbase;
+	if (!base) 
+		return NULL;
+	address = __pa(address);
+	addr = address & LARGE_PAGE_MASK; 
+	pbase = (pte_t *)page_address(base);
+	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
+		pbase[i] = mk_pte_phys(addr, 
+				      addr == address ? prot : PAGE_KERNEL);
+	}
+	return base;
+} 
+
+static void flush_kernel_map(void * address) 
+{ 
+	if (!test_bit(X86_FEATURE_SELFSNOOP, boot_cpu_data.x86_capability)) {
+		/* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */
+		if (boot_cpu_data.x86_model >= 4) 
+			asm volatile("wbinvd":::"memory"); 	
+	} 
+
+	/* Do global flush here to work around large page flushing errata 
+	   in some early Athlons */
+	__flush_tlb_all(); 	
+}
+
+static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) 
+{ 
+	set_pte_atomic(kpte, pte); 	/* change init_mm */
+#ifndef CONFIG_X86_PAE
+	{
+		struct list_head *l;
+		spin_lock(&mmlist_lock);
+		list_for_each(l, &init_mm.mmlist) { 
+			struct mm_struct *mm = list_entry(l, struct mm_struct, mmlist);
+			pmd_t *pmd = pmd_offset(pgd_offset(mm, address), address);
+			set_pte_atomic((pte_t *)pmd, pte);
+		} 
+		spin_unlock(&mmlist_lock);
+	}
+#endif
+}
+
+/* no more special protections in this 2/4MB area - revert to a
+   large page again. */
+static inline void revert_page(struct page *kpte_page, unsigned long address)
+{
+	pte_t *linear = (pte_t *) 
+		pmd_offset(pgd_offset(&init_mm, address), address);
+	set_pmd_pte(linear,  address,
+		mk_pte_phys(__pa(address & LARGE_PAGE_MASK),
+			    MAKE_GLOBAL(_KERNPG_TABLE|_PAGE_PSE)));
+}	
+ 
+/*
+ * Change the page attributes of an page in the linear mapping.
+ *
+ * This should be used when a page is mapped with a different caching policy
+ * than write-back somewhere - some CPUs do not like it when mappings with
+ * different caching policies exist. This changes the page attributes of the
+ * in kernel linear mapping too.
+ * 
+ * The caller needs to ensure that there are no conflicting mappings elsewhere.
+ * This function only deals with the kernel linear map.
+ * When page is in highmem it must never be kmap'ed.
+ */
+static int 
+__change_page_attr(struct page *page, pgprot_t prot, struct page **oldpage) 
+{ 
+	pte_t *kpte; 
+	unsigned long address;
+	struct page *kpte_page;
+
+#ifdef CONFIG_HIGHMEM
+	if (page >= highmem_start_page) 
+		BUG(); 
+#endif
+	address = (unsigned long)page_address(page);
+	kpte = lookup_address(address);
+	if (!kpte) 
+		return -EINVAL; 
+	kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+	if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { 
+		if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
+			pte_t old = *kpte;
+			pte_t standard = mk_pte(page, PAGE_KERNEL); 
+
+			set_pte_atomic(kpte, mk_pte(page, prot)); 
+			if (pte_same(old,standard))
+				atomic_inc(&kpte_page->count);
+		} else {
+			struct page *split = split_large_page(address, prot); 
+			if (!split)
+				return -ENOMEM;
+			atomic_inc(&kpte_page->count); 	
+			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+		}	
+	} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
+		set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
+		atomic_dec(&kpte_page->count); 
+	}
+
+	if (cpu_has_pse && (atomic_read(&kpte_page->count) == 1)) { 
+		*oldpage = kpte_page;
+		revert_page(kpte_page, address);
+	} 
+	return 0;
+} 
+
+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+{
+	int err = 0; 
+	struct page *fpage; 
+	int i; 
+
+	down_write(&init_mm.mmap_sem);
+	for (i = 0; i < numpages; i++, page++) { 
+		fpage = NULL;
+		err = __change_page_attr(page, prot, &fpage); 
+		if (err) 
+			break; 
+		if (fpage || i == numpages-1) { 
+			void *address = page_address(page);
+#ifdef CONFIG_SMP 
+			smp_call_function(flush_kernel_map, address, 1, 1);
+#endif	
+			flush_kernel_map(address);
+			if (fpage)
+				__free_page(fpage);
+		} 
+	} 	
+	up_write(&init_mm.mmap_sem); 
+	return err;
+}
+
+EXPORT_SYMBOL(change_page_attr);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/Makefile linux-bk/arch/ia64/Makefile
--- linux-2.4.19/arch/ia64/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/Makefile	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/boot/Makefile linux-bk/arch/ia64/boot/Makefile
--- linux-2.4.19/arch/ia64/boot/Makefile	2001-01-04 20:50:17.000000000 +0000
+++ linux-bk/arch/ia64/boot/Makefile	2002-11-22 15:35:31.000000000 +0000
@@ -27,6 +27,6 @@
 	-o bootloader
 
 clean:
-	rm -f $(TARGETS)
+	rm -f $(targets-y) $(OBJECTS)
 
 dep:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/config.in linux-bk/arch/ia64/config.in
--- linux-2.4.19/arch/ia64/config.in	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/config.in	2002-11-22 15:35:31.000000000 +0000
@@ -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,22 +71,18 @@
 	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 n
+	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 n
-	define_bool CONFIG_DEVFS_FS y
-	if [ "$CONFIG_DEVFS_FS" = "y" ]; then
-	  bool '    Enable DEVFS Debug Code' CONFIG_DEVFS_DEBUG n
-	fi
-	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL y
+			CONFIG_IA64_SGI_AUTOTEST
+	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL
 	define_bool CONFIG_DISCONTIGMEM y
 	define_bool CONFIG_IA64_MCA y
 	define_bool CONFIG_NUMA 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 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,22 +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
+  tristate 'Sound card support' CONFIG_SOUND
+  if [ "$CONFIG_SOUND" != "n" ]; then
+    source drivers/sound/Config.in
+  fi
+  endmenu
 
-source drivers/usb/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
@@ -271,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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/defconfig linux-bk/arch/ia64/defconfig
--- linux-2.4.19/arch/ia64/defconfig	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/defconfig	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/dig/setup.c linux-bk/arch/ia64/dig/setup.c
--- linux-2.4.19/arch/ia64/dig/setup.c	2001-04-05 19:51:47.000000000 +0000
+++ linux-bk/arch/ia64/dig/setup.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/Makefile linux-bk/arch/ia64/hp/Makefile
--- linux-2.4.19/arch/ia64/hp/Makefile	2001-01-04 20:50:17.000000000 +0000
+++ linux-bk/arch/ia64/hp/Makefile	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/common/Makefile linux-bk/arch/ia64/hp/common/Makefile
--- linux-2.4.19/arch/ia64/hp/common/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/common/Makefile	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/common/sba_iommu.c linux-bk/arch/ia64/hp/common/sba_iommu.c
--- linux-2.4.19/arch/ia64/hp/common/sba_iommu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/common/sba_iommu.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_console.c linux-bk/arch/ia64/hp/hpsim_console.c
--- linux-2.4.19/arch/ia64/hp/hpsim_console.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/hp/hpsim_console.c	1970-01-01 00:00:00.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_irq.c linux-bk/arch/ia64/hp/hpsim_irq.c
--- linux-2.4.19/arch/ia64/hp/hpsim_irq.c	2001-04-05 19:51:47.000000000 +0000
+++ linux-bk/arch/ia64/hp/hpsim_irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_machvec.c linux-bk/arch/ia64/hp/hpsim_machvec.c
--- linux-2.4.19/arch/ia64/hp/hpsim_machvec.c	2000-08-12 02:09:06.000000000 +0000
+++ linux-bk/arch/ia64/hp/hpsim_machvec.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,2 +0,0 @@
-#define MACHVEC_PLATFORM_NAME	hpsim
-#include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_setup.c linux-bk/arch/ia64/hp/hpsim_setup.c
--- linux-2.4.19/arch/ia64/hp/hpsim_setup.c	2001-07-31 17:30:08.000000000 +0000
+++ linux-bk/arch/ia64/hp/hpsim_setup.c	1970-01-01 00:00:00.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/hpsim_ssc.h linux-bk/arch/ia64/hp/hpsim_ssc.h
--- linux-2.4.19/arch/ia64/hp/hpsim_ssc.h	2000-02-07 02:42:40.000000000 +0000
+++ linux-bk/arch/ia64/hp/hpsim_ssc.h	1970-01-01 00:00:00.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/Makefile linux-bk/arch/ia64/hp/sim/Makefile
--- linux-2.4.19/arch/ia64/hp/sim/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/sim/Makefile	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_console.c linux-bk/arch/ia64/hp/sim/hpsim_console.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_console.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/sim/hpsim_console.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_irq.c linux-bk/arch/ia64/hp/sim/hpsim_irq.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/sim/hpsim_irq.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_machvec.c linux-bk/arch/ia64/hp/sim/hpsim_machvec.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_machvec.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/sim/hpsim_machvec.c	2002-11-22 15:35:31.000000000 +0000
@@ -0,0 +1,2 @@
+#define MACHVEC_PLATFORM_NAME	hpsim
+#include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_setup.c linux-bk/arch/ia64/hp/sim/hpsim_setup.c
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/sim/hpsim_setup.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/sim/hpsim_ssc.h linux-bk/arch/ia64/hp/sim/hpsim_ssc.h
--- linux-2.4.19/arch/ia64/hp/sim/hpsim_ssc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/sim/hpsim_ssc.h	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/zx1/Makefile linux-bk/arch/ia64/hp/zx1/Makefile
--- linux-2.4.19/arch/ia64/hp/zx1/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/zx1/Makefile	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/zx1/hpzx1_machvec.c linux-bk/arch/ia64/hp/zx1/hpzx1_machvec.c
--- linux-2.4.19/arch/ia64/hp/zx1/hpzx1_machvec.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/zx1/hpzx1_machvec.c	2002-11-22 15:35:33.000000000 +0000
@@ -0,0 +1,2 @@
+#define MACHVEC_PLATFORM_NAME	hpzx1
+#include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/hp/zx1/hpzx1_misc.c linux-bk/arch/ia64/hp/zx1/hpzx1_misc.c
--- linux-2.4.19/arch/ia64/hp/zx1/hpzx1_misc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/hp/zx1/hpzx1_misc.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/ia32/binfmt_elf32.c linux-bk/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.19/arch/ia64/ia32/binfmt_elf32.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/ia32/binfmt_elf32.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/ia32/ia32_traps.c linux-bk/arch/ia64/ia32/ia32_traps.c
--- linux-2.4.19/arch/ia64/ia32/ia32_traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/ia32/ia32_traps.c	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/Makefile linux-bk/arch/ia64/kernel/Makefile
--- linux-2.4.19/arch/ia64/kernel/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/Makefile	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/acpi.c linux-bk/arch/ia64/kernel/acpi.c
--- linux-2.4.19/arch/ia64/kernel/acpi.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/acpi.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/efi.c linux-bk/arch/ia64/kernel/efi.c
--- linux-2.4.19/arch/ia64/kernel/efi.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/efi.c	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/efi_stub.S linux-bk/arch/ia64/kernel/efi_stub.S
--- linux-2.4.19/arch/ia64/kernel/efi_stub.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/kernel/efi_stub.S	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/efivars.c linux-bk/arch/ia64/kernel/efivars.c
--- linux-2.4.19/arch/ia64/kernel/efivars.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/efivars.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/entry.S linux-bk/arch/ia64/kernel/entry.S
--- linux-2.4.19/arch/ia64/kernel/entry.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/entry.S	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/fw-emu.c linux-bk/arch/ia64/kernel/fw-emu.c
--- linux-2.4.19/arch/ia64/kernel/fw-emu.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/kernel/fw-emu.c	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/gate.S linux-bk/arch/ia64/kernel/gate.S
--- linux-2.4.19/arch/ia64/kernel/gate.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/gate.S	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/head.S linux-bk/arch/ia64/kernel/head.S
--- linux-2.4.19/arch/ia64/kernel/head.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/head.S	2002-11-22 15:35:32.000000000 +0000
@@ -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
-	;;
-	ldf.fill f126=[sp]
-	mov      f127=f0
-	br.ret.sptk.many rp
+	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
+	;;
+
+	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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/ia64_ksyms.c linux-bk/arch/ia64/kernel/ia64_ksyms.c
--- linux-2.4.19/arch/ia64/kernel/ia64_ksyms.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/ia64_ksyms.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/iosapic.c linux-bk/arch/ia64/kernel/iosapic.c
--- linux-2.4.19/arch/ia64/kernel/iosapic.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/iosapic.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/irq.c linux-bk/arch/ia64/kernel/irq.c
--- linux-2.4.19/arch/ia64/kernel/irq.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/irq.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/irq_ia64.c linux-bk/arch/ia64/kernel/irq_ia64.c
--- linux-2.4.19/arch/ia64/kernel/irq_ia64.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/kernel/irq_ia64.c	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/ivt.S linux-bk/arch/ia64/kernel/ivt.S
--- linux-2.4.19/arch/ia64/kernel/ivt.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/ivt.S	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/mca.c linux-bk/arch/ia64/kernel/mca.c
--- linux-2.4.19/arch/ia64/kernel/mca.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/mca.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/mca_asm.S linux-bk/arch/ia64/kernel/mca_asm.S
--- linux-2.4.19/arch/ia64/kernel/mca_asm.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/mca_asm.S	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/minstate.h linux-bk/arch/ia64/kernel/minstate.h
--- linux-2.4.19/arch/ia64/kernel/minstate.h	2001-07-31 17:30:08.000000000 +0000
+++ linux-bk/arch/ia64/kernel/minstate.h	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/pal.S linux-bk/arch/ia64/kernel/pal.S
--- linux-2.4.19/arch/ia64/kernel/pal.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/kernel/pal.S	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/palinfo.c linux-bk/arch/ia64/kernel/palinfo.c
--- linux-2.4.19/arch/ia64/kernel/palinfo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/palinfo.c	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/pci.c linux-bk/arch/ia64/kernel/pci.c
--- linux-2.4.19/arch/ia64/kernel/pci.c	2001-12-21 17:41:53.000000000 +0000
+++ linux-bk/arch/ia64/kernel/pci.c	2002-11-22 15:35:29.000000000 +0000
@@ -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))
 
-/* Macro to build a PCI configuration address to be passed as a parameter to SAL. */
+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;
 
-#define PCI_CONFIG_ADDRESS(dev, where) \
-	(((u64) dev->bus->number << 16) | ((u64) (dev->devfn & 0xff) << 8) | (where & 0xff))
+	result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data);
+
+	*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;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 1, &lval);
-	*value = lval;
-	return status;
+	return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
 }
 
+
 static int
-pci_conf_read_config_word(struct pci_dev *dev, int where, u16 *value)
+pci_sal_read_config_byte (struct pci_dev *dev, int where, u8 *value)
 {
-	s64 status;
-	u64 lval;
+	int result = 0;
+	u32 data = 0;
+
+	if (!value)
+		return -EINVAL;
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 2, &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_dword(struct pci_dev *dev, int where, u32 *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);
 
-	status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS(dev, where), 4, &lval);
-	*value = lval;
-	return status;
+	*value = (u16) data;
+
+	return result;
+}
+
+static int
+pci_sal_read_config_dword (struct pci_dev *dev, int where, u32 *value)
+{
+	if (!value)
+		return -EINVAL;
+
+	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,12 +342,45 @@
 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;
 }
 
 void
-pcibios_align_resource (void *data, struct resource *res, unsigned long size)
+pcibios_align_resource (void *data, struct resource *res,
+		        unsigned long size, unsigned long align)
 {
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon.c linux-bk/arch/ia64/kernel/perfmon.c
--- linux-2.4.19/arch/ia64/kernel/perfmon.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/perfmon.c	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon_generic.h linux-bk/arch/ia64/kernel/perfmon_generic.h
--- linux-2.4.19/arch/ia64/kernel/perfmon_generic.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/kernel/perfmon_generic.h	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon_itanium.h linux-bk/arch/ia64/kernel/perfmon_itanium.h
--- linux-2.4.19/arch/ia64/kernel/perfmon_itanium.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/kernel/perfmon_itanium.h	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/perfmon_mckinley.h linux-bk/arch/ia64/kernel/perfmon_mckinley.h
--- linux-2.4.19/arch/ia64/kernel/perfmon_mckinley.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/kernel/perfmon_mckinley.h	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/process.c linux-bk/arch/ia64/kernel/process.c
--- linux-2.4.19/arch/ia64/kernel/process.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/process.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/salinfo.c linux-bk/arch/ia64/kernel/salinfo.c
--- linux-2.4.19/arch/ia64/kernel/salinfo.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/kernel/salinfo.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/setup.c linux-bk/arch/ia64/kernel/setup.c
--- linux-2.4.19/arch/ia64/kernel/setup.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/setup.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/signal.c linux-bk/arch/ia64/kernel/signal.c
--- linux-2.4.19/arch/ia64/kernel/signal.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/signal.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/smp.c linux-bk/arch/ia64/kernel/smp.c
--- linux-2.4.19/arch/ia64/kernel/smp.c	2001-12-21 17:41:53.000000000 +0000
+++ linux-bk/arch/ia64/kernel/smp.c	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/smpboot.c linux-bk/arch/ia64/kernel/smpboot.c
--- linux-2.4.19/arch/ia64/kernel/smpboot.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/smpboot.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/sys_ia64.c linux-bk/arch/ia64/kernel/sys_ia64.c
--- linux-2.4.19/arch/ia64/kernel/sys_ia64.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/kernel/sys_ia64.c	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/time.c linux-bk/arch/ia64/kernel/time.c
--- linux-2.4.19/arch/ia64/kernel/time.c	2002-02-25 19:37:53.000000000 +0000
+++ linux-bk/arch/ia64/kernel/time.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/traps.c linux-bk/arch/ia64/kernel/traps.c
--- linux-2.4.19/arch/ia64/kernel/traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/traps.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/unaligned.c linux-bk/arch/ia64/kernel/unaligned.c
--- linux-2.4.19/arch/ia64/kernel/unaligned.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/unaligned.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/unwind.c linux-bk/arch/ia64/kernel/unwind.c
--- linux-2.4.19/arch/ia64/kernel/unwind.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/unwind.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/kernel/unwind_i.h linux-bk/arch/ia64/kernel/unwind_i.h
--- linux-2.4.19/arch/ia64/kernel/unwind_i.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/kernel/unwind_i.h	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/Makefile linux-bk/arch/ia64/lib/Makefile
--- linux-2.4.19/arch/ia64/lib/Makefile	2001-07-31 17:30:08.000000000 +0000
+++ linux-bk/arch/ia64/lib/Makefile	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/checksum.c linux-bk/arch/ia64/lib/checksum.c
--- linux-2.4.19/arch/ia64/lib/checksum.c	2001-07-31 17:30:08.000000000 +0000
+++ linux-bk/arch/ia64/lib/checksum.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/clear_page.S linux-bk/arch/ia64/lib/clear_page.S
--- linux-2.4.19/arch/ia64/lib/clear_page.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/lib/clear_page.S	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/copy_page.S linux-bk/arch/ia64/lib/copy_page.S
--- linux-2.4.19/arch/ia64/lib/copy_page.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/lib/copy_page.S	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/copy_page_mck.S linux-bk/arch/ia64/lib/copy_page_mck.S
--- linux-2.4.19/arch/ia64/lib/copy_page_mck.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/lib/copy_page_mck.S	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/copy_user.S linux-bk/arch/ia64/lib/copy_user.S
--- linux-2.4.19/arch/ia64/lib/copy_user.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/lib/copy_user.S	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/do_csum.S linux-bk/arch/ia64/lib/do_csum.S
--- linux-2.4.19/arch/ia64/lib/do_csum.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/lib/do_csum.S	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/ip_fast_csum.S linux-bk/arch/ia64/lib/ip_fast_csum.S
--- linux-2.4.19/arch/ia64/lib/ip_fast_csum.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/lib/ip_fast_csum.S	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/memcpy_mck.S linux-bk/arch/ia64/lib/memcpy_mck.S
--- linux-2.4.19/arch/ia64/lib/memcpy_mck.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/ia64/lib/memcpy_mck.S	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/memset.S linux-bk/arch/ia64/lib/memset.S
--- linux-2.4.19/arch/ia64/lib/memset.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/lib/memset.S	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/lib/swiotlb.c linux-bk/arch/ia64/lib/swiotlb.c
--- linux-2.4.19/arch/ia64/lib/swiotlb.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/lib/swiotlb.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/fault.c linux-bk/arch/ia64/mm/fault.c
--- linux-2.4.19/arch/ia64/mm/fault.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/mm/fault.c	2002-11-22 15:35:33.000000000 +0000
@@ -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
@@ -194,13 +203,11 @@
 	return;
 
   out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
+	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/init.c linux-bk/arch/ia64/mm/init.c
--- linux-2.4.19/arch/ia64/mm/init.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/mm/init.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/mm/tlb.c linux-bk/arch/ia64/mm/tlb.c
--- linux-2.4.19/arch/ia64/mm/tlb.c	2001-11-09 22:26:17.000000000 +0000
+++ linux-bk/arch/ia64/mm/tlb.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/README linux-bk/arch/ia64/sn/fakeprom/README
--- linux-2.4.19/arch/ia64/sn/fakeprom/README	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/sn/fakeprom/README	2002-11-22 15:35:30.000000000 +0000
@@ -71,7 +71,7 @@
     1GB*<dn>, where dn is the digit number. The amount of memory
     is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
 
-    SN1 doesnt support dimms this small but small memory systems 
+    SN1 doesn't support dimms this small but small memory systems 
     boot faster on Medusa.
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/fpmem.c linux-bk/arch/ia64/sn/fakeprom/fpmem.c
--- linux-2.4.19/arch/ia64/sn/fakeprom/fpmem.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/sn/fakeprom/fpmem.c	2002-11-22 15:35:28.000000000 +0000
@@ -18,7 +18,7 @@
  */
 
 #include <linux/config.h>
-#include <asm/efi.h>
+#include <linux/efi.h>
 #include "fpmem.h"
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/fakeprom/fw-emu.c linux-bk/arch/ia64/sn/fakeprom/fw-emu.c
--- linux-2.4.19/arch/ia64/sn/fakeprom/fw-emu.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/sn/fakeprom/fw-emu.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/io/Makefile linux-bk/arch/ia64/sn/io/Makefile
--- linux-2.4.19/arch/ia64/sn/io/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/sn/io/Makefile	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/io/efi-rtc.c linux-bk/arch/ia64/sn/io/efi-rtc.c
--- linux-2.4.19/arch/ia64/sn/io/efi-rtc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-bk/arch/ia64/sn/io/efi-rtc.c	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/io/pci_dma.c linux-bk/arch/ia64/sn/io/pci_dma.c
--- linux-2.4.19/arch/ia64/sn/io/pci_dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/ia64/sn/io/pci_dma.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/kernel/llsc4.c linux-bk/arch/ia64/sn/kernel/llsc4.c
--- linux-2.4.19/arch/ia64/sn/kernel/llsc4.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/ia64/sn/kernel/llsc4.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/kernel/misctest.c linux-bk/arch/ia64/sn/kernel/misctest.c
--- linux-2.4.19/arch/ia64/sn/kernel/misctest.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/ia64/sn/kernel/misctest.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/sn/kernel/sn_ksyms.c linux-bk/arch/ia64/sn/kernel/sn_ksyms.c
--- linux-2.4.19/arch/ia64/sn/kernel/sn_ksyms.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/ia64/sn/kernel/sn_ksyms.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/tools/Makefile linux-bk/arch/ia64/tools/Makefile
--- linux-2.4.19/arch/ia64/tools/Makefile	2002-02-25 19:37:53.000000000 +0000
+++ linux-bk/arch/ia64/tools/Makefile	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/tools/print_offsets.c linux-bk/arch/ia64/tools/print_offsets.c
--- linux-2.4.19/arch/ia64/tools/print_offsets.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/ia64/tools/print_offsets.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/ia64/vmlinux.lds.S linux-bk/arch/ia64/vmlinux.lds.S
--- linux-2.4.19/arch/ia64/vmlinux.lds.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/ia64/vmlinux.lds.S	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/amiga/config.c linux-bk/arch/m68k/amiga/config.c
--- linux-2.4.19/arch/m68k/amiga/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/amiga/config.c	2002-11-22 15:35:23.000000000 +0000
@@ -20,6 +20,7 @@
 #include <linux/console.h>
 #include <linux/rtc.h>
 #include <linux/init.h>
+#include <linux/vt_kern.h>
 #ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
 #endif
@@ -128,8 +129,6 @@
 	"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
 #endif
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
-
 
     /*
      *  Motherboard Resources present in all Amiga models
@@ -390,10 +389,12 @@
     request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
 
   mach_sched_init      = amiga_sched_init;
+#ifdef CONFIG_VT
   mach_keyb_init       = amiga_keyb_init;
   mach_kbdrate         = amiga_kbdrate;
   mach_kbd_translate   = amiga_kbd_translate;
-  SYSRQ_KEY            = 0xff;
+  kd_mksound           = amiga_mksound;
+#endif
   mach_init_IRQ        = amiga_init_IRQ;
   mach_default_handler = &amiga_default_handler;
   mach_request_irq     = amiga_request_irq;
@@ -434,8 +435,8 @@
 #ifdef CONFIG_DUMMY_CONSOLE
   conswitchp           = &dummy_con;
 #endif
-  kd_mksound           = amiga_mksound;
 #ifdef CONFIG_MAGIC_SYSRQ
+  SYSRQ_KEY            = 0xff;
   mach_sysrq_key = 0x5f;	     /* HELP */
   mach_sysrq_shift_state = 0x03; /* SHIFT+ALTGR */
   mach_sysrq_shift_mask = 0xff;  /* all modifiers except CapsLock */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/apollo/config.c linux-bk/arch/m68k/apollo/config.c
--- linux-2.4.19/arch/m68k/apollo/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/apollo/config.c	2002-11-22 15:35:27.000000000 +0000
@@ -5,6 +5,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/rtc.h>
+#include <linux/vt_kern.h>
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
@@ -42,7 +43,6 @@
 extern void dn_dummy_waitbut(void);
 extern struct fb_info *dn_fb_init(long *);
 extern void dn_dummy_debug_init(void);
-extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void dn_dummy_video_setup(char *,int *);
 extern void dn_process_int(int irq, struct pt_regs *fp);
 #ifdef CONFIG_HEARTBEAT
@@ -166,8 +166,11 @@
 	dn_setup_model();	
 
 	mach_sched_init=dn_sched_init; /* */
+#ifdef CONFIG_VT
 	mach_keyb_init=dn_keyb_init;
 	mach_kbdrate=dn_dummy_kbdrate;
+	kd_mksound	     = dn_mksound;
+#endif
 	mach_init_IRQ=dn_init_IRQ;
 	mach_default_handler=NULL;
 	mach_request_irq     = dn_request_irq;
@@ -189,7 +192,6 @@
 #ifdef CONFIG_DUMMY_CONSOLE
         conswitchp           = &dummy_con;
 #endif
-	kd_mksound	     = dn_mksound;
 #ifdef CONFIG_HEARTBEAT
   	mach_heartbeat = dn_heartbeat;
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/apollo/dn_ints.c linux-bk/arch/m68k/apollo/dn_ints.c
--- linux-2.4.19/arch/m68k/apollo/dn_ints.c	2001-03-07 03:44:35.000000000 +0000
+++ linux-bk/arch/m68k/apollo/dn_ints.c	2002-11-22 15:35:32.000000000 +0000
@@ -12,11 +12,6 @@
 
 static irq_handler_t dn_irqs[16];
 
-extern void write_keyb_cmd(u_short length, u_char *cmd);
-static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
-		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
-
-extern void dn_serial_print (const char *str);
 void dn_process_int(int irq, struct pt_regs *fp) {
 
 
@@ -120,6 +115,11 @@
 
 }
 
+#ifdef CONFIG_VT
+extern void write_keyb_cmd(u_short length, u_char *cmd);
+static char BellOnCommand[] =  { 0xFF, 0x21, 0x81 },
+		    BellOffCommand[] = { 0xFF, 0x21, 0x82 };
+
 static void dn_nosound (unsigned long ignored) {
 
 	write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
@@ -141,6 +141,8 @@
 	else
 		write_keyb_cmd(sizeof(BellOffCommand),BellOffCommand);
 }
+#endif /* CONFIG_VT */
+
 
 void dn_dummy_video_setup(char *options,int *ints) {
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/atari/Makefile linux-bk/arch/m68k/atari/Makefile
--- linux-2.4.19/arch/m68k/atari/Makefile	2000-12-29 22:07:20.000000000 +0000
+++ linux-bk/arch/m68k/atari/Makefile	2002-11-22 15:35:24.000000000 +0000
@@ -11,10 +11,12 @@
 
 export-objs	:= atari_ksyms.o
 
-obj-y		:= config.o time.o debug.o atakeyb.o ataints.o stdma.o \
-			atasound.o joystick.o stram.o atari_ksyms.o
+obj-y		:= config.o time.o debug.o ataints.o stdma.o \
+			atasound.o stram.o atari_ksyms.o
 
-ifdef CONFIG_PCI
+obj-$(CONFIG_VT)	+= atakeyb.o joystick.o
+
+ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_HADES)	+= hades-pci.o
 endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/atari/config.c linux-bk/arch/m68k/atari/config.c
--- linux-2.4.19/arch/m68k/atari/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/atari/config.c	2002-11-22 15:35:24.000000000 +0000
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/vt_kern.h>
 
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
@@ -102,7 +103,6 @@
 	"0.\r\000\000\000\000\000\000\000\000\000\000\000\000\000";	/* 0x70 - 0x7f */
 #endif
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 
 /* I've moved hwreg_present() and hwreg_present_bywrite() out into
  * mm/hwtest.c, to avoid having multiple copies of the same routine
@@ -254,13 +254,13 @@
                                            to 4GB. */
 
     mach_sched_init      = atari_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
     mach_kbd_translate   = atari_kbd_translate;
-#ifdef CONFIG_MAGIC_SYSRQ
-    SYSRQ_KEY            = 0xff;
-#endif
     mach_kbd_leds        = atari_kbd_leds;
+    kd_mksound		 = atari_mksound;
+#endif
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
     mach_free_irq        = atari_free_irq;
@@ -278,8 +278,8 @@
     conswitchp	         = &dummy_con;
 #endif
     mach_max_dma_address = 0xffffff;
-    kd_mksound		 = atari_mksound;
 #ifdef CONFIG_MAGIC_SYSRQ
+    SYSRQ_KEY            = 0xff;
     mach_sysrq_key = 98;          /* HELP */
     mach_sysrq_shift_state = 8;   /* Alt */
     mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/bvme6000/config.c linux-bk/arch/m68k/bvme6000/config.c
--- linux-2.4.19/arch/m68k/bvme6000/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/bvme6000/config.c	2002-11-22 15:35:23.000000000 +0000
@@ -135,8 +135,10 @@
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = bvme6000_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = bvme6000_keyb_init;
     mach_kbdrate         = bvme6000_kbdrate;
+#endif
     mach_init_IRQ        = bvme6000_init_IRQ;
     mach_gettimeoffset   = bvme6000_gettimeoffset;
     mach_gettod  	 = bvme6000_gettod;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/bvme6000/rtc.c linux-bk/arch/m68k/bvme6000/rtc.c
--- linux-2.4.19/arch/m68k/bvme6000/rtc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/bvme6000/rtc.c	2002-11-22 15:35:23.000000000 +0000
@@ -94,7 +94,7 @@
 
 		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
 
-		if ((mon > 12) || (day == 0))
+		if ((mon > 12) || (mon < 1) || (day == 0))
 			return -EINVAL;
 
 		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/config.in linux-bk/arch/m68k/config.in
--- linux-2.4.19/arch/m68k/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/config.in	2002-11-22 15:35:32.000000000 +0000
@@ -141,7 +141,7 @@
    fi
    dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
    if [ "$CONFIG_PRINTER" != "n" ]; then
-      bool '    Support IEEE1284 status readback' CONFIG_PARPORT_1284
+      bool '    IEEE 1284 transfer modes' CONFIG_PARPORT_1284
    fi
 fi
 
@@ -376,6 +376,11 @@
 mainmenu_option next_comment
 comment 'Character devices'
  
+bool 'Virtual terminal' CONFIG_VT
+if [ "$CONFIG_VT" = "y" ]; then
+   bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
+fi
+
 if [ "$CONFIG_Q40" = "y" ]; then
    tristate 'Q40 Standard/generic serial support' CONFIG_SERIAL
 fi
@@ -391,13 +396,6 @@
    bool '    Support the Bell Technologies HUB6 card' CONFIG_HUB6
 fi
 
-if [ "$CONFIG_VME" = "n" ]; then
-   define_bool CONFIG_VT y
-   if [ "$CONFIG_VT" = "y" ]; then
-      bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE
-   fi
-fi
-
 if [ "$CONFIG_ATARI" = "y" ]; then
    define_bool CONFIG_NVRAM y
 fi
@@ -408,7 +406,7 @@
       define_bool CONFIG_BUSMOUSE y
    fi
 fi
-if [ "$CONFIG_ATARI" = "y" ]; then
+if [ "$CONFIG_ATARI" = "y" -a "$CONFIG_VT" = "y" ]; then
    tristate 'Atari mouse support' CONFIG_ATARIMOUSE
    if [ "$CONFIG_ATARIMOUSE" != "n" ]; then
       define_bool CONFIG_BUSMOUSE y
@@ -430,16 +428,16 @@
    if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
       tristate 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET_SERIAL
    fi
+   tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
+   fi
 fi
 if [ "$CONFIG_PARPORT" = "n" ]; then
    if [ "$CONFIG_ZORRO" = "y" ]; then
       tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
       dep_tristate '  GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
       dep_tristate '  GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
-      tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-        tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
-      fi
    fi
 fi
 if [ "$CONFIG_MAC" = "y" ]; then
@@ -464,6 +462,20 @@
 if [ "$CONFIG_HP300" = "y" -a "$CONFIG_DIO" = "y" ]; then
    tristate 'HP DCA serial support' CONFIG_HPDCA
 fi
+if [ "$CONFIG_MVME147" = "y" ]; then
+   bool 'SCC support for MVME147 serial ports' CONFIG_MVME147_SCC
+fi
+if [ "$CONFIG_MVME16x" = "y" ]; then
+   bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
+   bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
+fi
+if [ "$CONFIG_BVME6000" = "y" ]; then
+   bool 'SCC support for BVME6000 serial ports' CONFIG_BVME6000_SCC
+fi
+if [ "$CONFIG_APOLLO" = "y" ]; then
+   bool 'Support for DN serial port (dummy)' CONFIG_DN_SERIAL
+   define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
+fi 
 
 if [ "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
    bool 'Sun3/3x builtin serial support' CONFIG_SUN3X_ZS
@@ -483,37 +495,16 @@
    define_bool CONFIG_SBUS n
 fi
 
-if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" -o \
-     "$CONFIG_MAC" = "y" -o "$CONFIG_HP300" = "y" -o \
-     "$CONFIG_SUN3" = "y" -o "$CONFIG_SUN3X" = "y" ]; then
-   if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
-        "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
-        "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
-        "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
-        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" -o \
-	"$CONFIG_SERIAL" = "y" ]; then
-      bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
-   fi
-fi
-if [ "$CONFIG_VME" = "y" ]; then
-   define_bool CONFIG_SERIAL_CONSOLE y
-   if [ "$CONFIG_MVME147" = "y" ]; then
-      bool 'SCC support for MVME147 serial ports' CONFIG_MVME147_SCC
-   fi
-   if [ "$CONFIG_MVME16x" = "y" ]; then
-      bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
-      bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
-   fi
-   if [ "$CONFIG_BVME6000" = "y" ]; then
-      bool 'SCC support for BVME6000 serial ports' CONFIG_BVME6000_SCC
-   fi
-fi
-if [ "$CONFIG_APOLLO" = "y" ]; then
-   bool 'Support for DN serial port (dummy)' CONFIG_DN_SERIAL
+if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
+     "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
+     "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o "$CONFIG_GVPIOEXT" = "y" -o \
+     "$CONFIG_MULTIFACE_III_TTY" = "y" -o "$CONFIG_HPDCA" = "y" -o \
+     "$CONFIG_SUN3X_ZS" = "y" -o "$CONFIG_SERIAL" = "y" -o \
+     "$CONFIG_MVME147_SCC" -o "$CONFIG_SERIAL167" = "y" -o \
+     "$CONFIG_MVME162_SCC" -o "$CONFIG_BVME6000_SCC" = "y" -o \
+     "$CONFIG_DN_SERIAL" -o ]; then
    bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
-
-   define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
-fi 
+fi
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
@@ -539,7 +530,7 @@
 mainmenu_option next_comment
 comment 'Sound support'
 
-tristate 'Sound support' CONFIG_SOUND
+tristate 'Sound card support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
    source drivers/sound/dmasound/Config.in
 fi
@@ -547,7 +538,7 @@
 
 source fs/Config.in
 
-if [ "$CONFIG_VME" = "n" ]; then
+if [ "$CONFIG_VT" = "y" ]; then
    mainmenu_option next_comment
    comment 'Console drivers'
    source drivers/video/Config.in
@@ -565,3 +556,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/config.c linux-bk/arch/m68k/hp300/config.c
--- linux-2.4.19/arch/m68k/hp300/config.c	1999-08-26 19:42:31.000000000 +0000
+++ linux-bk/arch/m68k/hp300/config.c	2002-11-22 15:35:23.000000000 +0000
@@ -17,7 +17,6 @@
 #include <linux/init.h>
 #include <asm/machdep.h>
 #include <asm/blinken.h>
-#include <asm/io.h>                               /* readb() and writeb() */
 #include <asm/hwtest.h>                           /* hwreg_present() */
 
 #include "ints.h"
@@ -29,10 +28,9 @@
 
 #ifdef CONFIG_VT
 extern int hp300_keyb_init(void);
-#else
-/* Dummy function for when there is no keyboard. */
-int __init hp300_keyb_init(void)
+static int hp300_kbdrate(struct kbd_repeat *k)
 {
+  return 0;
 }
 #endif
 
@@ -46,15 +44,6 @@
 }
 #endif
 
-static int hp300_kbdrate(struct kbd_repeat *k)
-{
-  return 0;
-}
-
-static void hp300_kbd_leds(unsigned int leds)
-{
-}
-
 static void hp300_get_model(char *model)
 {
   strcpy(model, "HP9000/300");
@@ -63,9 +52,10 @@
 void __init config_hp300(void)
 {
   mach_sched_init      = hp300_sched_init;
+#ifdef CONFIG_VT
   mach_keyb_init       = hp300_keyb_init;
   mach_kbdrate         = hp300_kbdrate;
-  mach_kbd_leds        = hp300_kbd_leds;
+#endif
   mach_init_IRQ        = hp300_init_IRQ;
   mach_request_irq     = hp300_request_irq;
   mach_free_irq        = hp300_free_irq;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/hil.c linux-bk/arch/m68k/hp300/hil.c
--- linux-2.4.19/arch/m68k/hp300/hil.c	1999-08-26 19:42:31.000000000 +0000
+++ linux-bk/arch/m68k/hp300/hil.c	2002-11-22 15:35:32.000000000 +0000
@@ -25,12 +25,12 @@
 #define	HIL_BUSY		0x02
 #define	HIL_DATA_RDY		0x01
 
-#define hil_busy()		(readb(HILBASE + HIL_CMD) & HIL_BUSY)
-#define hil_data_available()	(readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
-#define hil_status()		(readb(HILBASE + HIL_CMD))
-#define hil_command(x)		do { writeb((x), HILBASE + HIL_CMD); } while (0)
-#define hil_read_data()		(readb(HILBASE + HIL_DATA))
-#define hil_write_data(x)	do { writeb((x), HILBASE + HIL_DATA); } while (0)
+#define hil_busy()		(in_8(HILBASE + HIL_CMD) & HIL_BUSY)
+#define hil_data_available()	(in_8(HILBASE + HIL_CMD) & HIL_DATA_RDY)
+#define hil_status()		(in_8(HILBASE + HIL_CMD))
+#define hil_command(x)		out_8(HILBASE + HIL_CMD, (x))
+#define hil_read_data()		(in_8(HILBASE + HIL_DATA))
+#define hil_write_data(x)	out_8(HILBASE + HIL_DATA, (x))
 
 #define	HIL_SETARD		0xA0		/* set auto-repeat delay */
 #define	HIL_SETARR		0xA2		/* set auto-repeat rate */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/ints.c linux-bk/arch/m68k/hp300/ints.c
--- linux-2.4.19/arch/m68k/hp300/ints.c	1999-09-08 18:59:00.000000000 +0000
+++ linux-bk/arch/m68k/hp300/ints.c	2002-11-22 15:35:25.000000000 +0000
@@ -142,7 +142,9 @@
         }
         /* remove the entry after t: */
         t->next->flags = IRQ_FLG_STD;
-        t->next->dev_id = t->next->devname = t->next->handler = NULL;
+        t->next->dev_id = NULL;
+	t->next->devname = NULL;
+	t->next->handler = NULL;
         t->next = t->next->next;
         
 	spin_unlock_irqrestore(&irqlist_lock, flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/hp300/time.c linux-bk/arch/m68k/hp300/time.c
--- linux-2.4.19/arch/m68k/hp300/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/hp300/time.c	2002-11-22 15:35:32.000000000 +0000
@@ -40,7 +40,7 @@
 {
   unsigned long tmp;
   void (*vector)(int, void *, struct pt_regs *) = dev_id;
-  readb(CLOCKBASE + CLKSR);
+  in_8(CLOCKBASE + CLKSR);
   asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE));
   vector(irq, NULL, regs);
 }
@@ -51,25 +51,25 @@
   unsigned char lsb, msb1, msb2;
   unsigned short ticks;
 
-  msb1 = readb(CLOCKBASE + 5);
-  lsb = readb(CLOCKBASE + 7);
-  msb2 = readb(CLOCKBASE + 5);
+  msb1 = in_8(CLOCKBASE + 5);
+  lsb = in_8(CLOCKBASE + 7);
+  msb2 = in_8(CLOCKBASE + 5);
   if (msb1 != msb2)
     /* A carry happened while we were reading.  Read it again */
-    lsb = readb(CLOCKBASE + 7);
+    lsb = in_8(CLOCKBASE + 7);
   ticks = INTVAL - ((msb2 << 8) | lsb);
   return (USECS_PER_JIFFY * ticks) / INTVAL;
 }
 
 void __init hp300_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
-  writeb(0x1, CLOCKBASE + CLKCR2);		/* select CR1 */
-  writeb(0x1, CLOCKBASE + CLKCR1);		/* reset */
+  out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
+  out_8(CLOCKBASE + CLKCR1, 0x1);		/* reset */
 
   asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
 
   sys_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
 
-  writeb(0x1, CLOCKBASE + CLKCR2);		/* select CR1 */
-  writeb(0x40, CLOCKBASE + CLKCR1);		/* enable irq */
+  out_8(CLOCKBASE + CLKCR2, 0x1);		/* select CR1 */
+  out_8(CLOCKBASE + CLKCR1, 0x40);		/* enable irq */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/entry.S linux-bk/arch/m68k/kernel/entry.S
--- linux-2.4.19/arch/m68k/kernel/entry.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/kernel/entry.S	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/head.S linux-bk/arch/m68k/kernel/head.S
--- linux-2.4.19/arch/m68k/kernel/head.S	2001-06-12 02:15:27.000000000 +0000
+++ linux-bk/arch/m68k/kernel/head.S	2002-11-22 15:35:30.000000000 +0000
@@ -310,8 +310,11 @@
 .globl SYMBOL_NAME(mvme_bdid)
 #endif
 #ifdef CONFIG_Q40
-.globl SYMBOL_NAME(q40_mem_cptr)	
-#endif		
+.globl SYMBOL_NAME(q40_mem_cptr)
+#endif
+#ifdef CONFIG_HP300
+.globl SYMBOL_NAME(hp300_phys_ram_base)
+#endif
 
 CPUTYPE_040	= 1	/* indicates an 040 */
 CPUTYPE_060	= 2	/* indicates an 060 */
@@ -596,6 +599,64 @@
 __INIT
 ENTRY(__start)
 
+#ifdef CONFIG_HP300
+/* This is a hack.  The HP NetBSD bootloader loads us at an arbitrary
+   address (apparently 0xff002000 in practice) which is not good if we need
+   to be able to map this to VA 0x1000.  We could do it with pagetables but
+   a better solution seems to be to relocate the kernel in physical memory
+   before we start.  
+	
+   So, we copy the entire kernel image (code+data+bss) down to the 16MB
+   boundary that marks the start of RAM.  This is slightly tricky because
+   we must not overwrite the copying code itself. :-)  */
+
+/* 15/5/98.  The start address of physical RAM changes depending on how much
+   RAM is present.  This is actually a blessing in disguise as it provides
+   a way for us to work out the RAM size rather than hardwiring it.  */
+
+	lea	%pc@(_start),%a0
+	movel	%a0,%d6
+	and	#0xffff0000, %d6
+	lea	%pc@(SYMBOL_NAME(hp300_phys_ram_base)),%a0
+	movel	%d6, %a0@
+	movel	%pc@(L(custom)),%a3
+	moveb	#0xfe,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	lea	%pc@(Lcopystart),%a0
+	lea	%pc@(Lcopyend),%a1
+	movel	%d6,%a2			/* Start of physical RAM */
+1:	moveb	%a0@+,%d0
+	moveb	%d0,%a2@+
+	cmpl	%a0,%a1
+	jbne	1b
+	movel	%d6,%a2
+	moveb	#0xfd,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	lea	%pc@(_stext),%a0
+	lea	%pc@(_end),%a1
+	jmp	%a2@
+
+Lcopystart:
+	moveb	#0xf7,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	movel	%d6,%a2	/* Start of kernel */
+	add	#0x1000,%a2
+1:	moveb	%a0@+,%d0
+	moveb	%d0,%a2@+
+	cmpl	%a0,%a1
+	jbne	1b
+	moveb	#0,%d7
+	moveb	%d7,%a3@(0x1ffff)
+	movel	%d6,%a0
+	addl	#Lstart1,%a0
+	jmp	%a0@
+Lcopyend:	
+
+Lstart1:
+	moveb	#0x3f,%d7
+	moveb	%d7,%a3@(0x1ffff)
+#endif /* CONFIG_HP300 */
+
 /*
  * Setup initial stack pointer
  */
@@ -605,6 +666,7 @@
  * Record the CPU and machine type.
  */
 
+#ifndef CONFIG_HP300
 	get_bi_record	BI_MACHTYPE
 	lea	%pc@(SYMBOL_NAME(m68k_machtype)),%a1
 	movel	%a0@,%a1@
@@ -620,6 +682,23 @@
 	get_bi_record	BI_CPUTYPE
 	lea	%pc@(SYMBOL_NAME(m68k_cputype)),%a1
 	movel	%a0@,%a1@
+#else /* CONFIG_HP300 */
+	/* FIXME HP300 doesn't use bootinfo yet */
+	movel	#MACH_HP300,%d4
+	lea	%pc@(SYMBOL_NAME(m68k_machtype)),%a0
+	movel	%d4,%a0@
+	movel	#FPU_68881,%d0
+	lea	%pc@(SYMBOL_NAME(m68k_fputype)),%a0
+	movel	%d0,%a0@
+	movel	#MMU_68030,%d0
+	lea	%pc@(SYMBOL_NAME(m68k_mmutype)),%a0
+	movel	%d0,%a0@
+	movel	#CPU_68030,%d0
+	lea	%pc@(SYMBOL_NAME(m68k_cputype)),%a0
+	movel	%d0,%a0@
+
+	leds(0x1)
+#endif /* CONFIG_HP300 */
 
 #ifdef CONFIG_MAC
 /*
@@ -893,6 +972,9 @@
 
 	putc	'\n'
 	putc	'A'
+#ifdef CONFIG_HP300
+	leds(0x2)
+#endif /* CONFIG_HP300 */
 	dputn	%pc@(L(cputype))
 	dputn	%pc@(SYMBOL_NAME(m68k_supervisor_cachemode))
 	dputn	%pc@(SYMBOL_NAME(m68k_pgtable_cachemode))
@@ -1490,6 +1572,7 @@
 
 	movel	ARG1,%d0
 	lea	%pc@(SYMBOL_NAME(_end)),%a0
+#ifndef CONFIG_HP300
 1:	tstw	%a0@(BIR_TAG)
 	jeq	3f
 	cmpw	%a0@(BIR_TAG),%d0
@@ -1503,6 +1586,7 @@
 3:	moveq	#-1,%d0
 	lea	%a0@(BIR_SIZE),%a0
 4:
+#endif /* CONFIG_HP300 */
 func_return	get_bi_record
 
 
@@ -3286,14 +3370,16 @@
 
 	/* Calculate font size */
 
-#if   defined(FONT_8x8)
+#if   defined(FONT_8x8) && defined(CONFIG_FONT_8x8)
 	lea	%pc@(SYMBOL_NAME(font_vga_8x8)), %a0
-#elif defined(FONT_8x16)
+#elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16)
 	lea	%pc@(SYMBOL_NAME(font_vga_8x16)),%a0
-#elif defined(FONT_6x11)
+#elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11)
 	lea	%pc@(SYMBOL_NAME(font_vga_6x11)),%a0
-#else	/*   (FONT_8x8) default */
+#elif defined(CONFIG_FONT_8x8) /* default *
 	lea	%pc@(SYMBOL_NAME(font_vga_8x8)), %a0
+#else /* no compiled-in font */
+	lea	0,%a0
 #endif
 
 	/*
@@ -3302,6 +3388,8 @@
 	 */
 	lea	%pc@(L(console_font)),%a1
 	movel	%a0,%a1@	/* store pointer to struct fbcon_font_desc in Lconsole_font */
+	tstl	%a0
+	jeq	1f
 
 	/*
 	 *	Calculate global maxs
@@ -3329,7 +3417,7 @@
 	/*
 	 * Initialization is complete
 	 */
-	moveml	%sp@+,%a0-%a4/%d0-%d7
+1:	moveml	%sp@+,%a0-%a4/%d0-%d7
 	rts
 
 L(console_put_stats):
@@ -3415,6 +3503,8 @@
 	lea	%pc@(L(mac_rowbytes)),%a0
 	movel	%a0@,%d5
 	movel	%pc@(L(console_font)),%a0
+	tstl	%a0
+	jeq	1f
 	mulul	%a0@(FBCON_FONT_DESC_HEIGHT),%d5	/* account for # scan lines per character */
 	addal	%d5,%a2
 
@@ -3469,13 +3559,15 @@
 	movel	%d0,%a1@+
 	dbra	%d6,console_scroll_clear_loop
 
-	moveml	%sp@+,%a0-%a4/%d0-%d7
+1:	moveml	%sp@+,%a0-%a4/%d0-%d7
 	rts
 
 
 func_start	console_putc,%a0/%a1/%d0-%d7
 
 	is_not_mac(console_exit)
+	tstl	%pc@(L(console_font))
+	jeq	console_exit
 
 	/* Output character in d7 on console.
 	 */
@@ -3747,7 +3839,12 @@
 __INITDATA
 	.align	4
 
-#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || defined(CONFIG_HP300)
+#ifdef CONFIG_HP300
+SYMBOL_NAME_LABEL(hp300_phys_ram_base)
+#endif
+
+#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
+    defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
 L(custom):
 L(iobase):
 	.long 0
@@ -3838,8 +3935,6 @@
 LSRB0        = 0x10412
 LTHRB0       = 0x10416
 LCPUCTRL     = 0x10100
-L(iobase):
-        .long 0
 #endif
 
 __FINIT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/setup.c linux-bk/arch/m68k/kernel/setup.c
--- linux-2.4.19/arch/m68k/kernel/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/kernel/setup.c	2002-11-22 15:35:33.000000000 +0000
@@ -34,6 +34,7 @@
 #endif
 #ifdef CONFIG_ATARI
 #include <asm/atarihw.h>
+#include <asm/atari_stram.h>
 #endif
 #ifdef CONFIG_SUN3X
 #include <asm/dvma.h>
@@ -71,11 +72,12 @@
 
 void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
 /* machine dependent keyboard functions */
+#ifdef CONFIG_VT
 int (*mach_keyb_init) (void) __initdata = NULL;
 int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
 void (*mach_kbd_leds) (unsigned int) = NULL;
 int (*mach_kbd_translate)(unsigned char scancode, unsigned char *keycode, char raw_mode) = NULL;
-unsigned int SYSRQ_KEY;
+#endif
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) __initdata = NULL;
 void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
@@ -104,6 +106,7 @@
 #endif
 
 #ifdef CONFIG_MAGIC_SYSRQ
+unsigned int SYSRQ_KEY;
 int mach_sysrq_key = -1;
 int mach_sysrq_shift_state = 0;
 int mach_sysrq_shift_mask = 0;
@@ -218,8 +221,20 @@
 	int i;
 	char *p, *q;
 
-	/* The bootinfo is located right after the kernel bss */
-	m68k_parse_bootinfo((const struct bi_record *)&_end);
+	if (!MACH_IS_HP300) {
+		/* The bootinfo is located right after the kernel bss */
+		m68k_parse_bootinfo((const struct bi_record *)&_end);
+	} else {
+		/* FIXME HP300 doesn't use bootinfo yet */
+		extern unsigned long hp300_phys_ram_base;
+		unsigned long hp300_mem_size = 0xffffffff-hp300_phys_ram_base;
+		m68k_cputype = CPU_68030;
+		m68k_fputype = FPU_68882;
+		m68k_memory[0].addr = hp300_phys_ram_base;
+		/* 0.5M fudge factor */
+		m68k_memory[0].size = hp300_mem_size-512*1024;
+		m68k_num_memory++;
+	}
 
 	if (CPU_IS_040)
 		m68k_is040or060 = 4;
@@ -372,7 +387,7 @@
 
 #ifdef CONFIG_ATARI
 	if (MACH_IS_ATARI)
-		atari_stram_reserve_pages(availmem);
+		atari_stram_reserve_pages((void *)availmem);
 #endif
 #ifdef CONFIG_SUN3X
 	if (MACH_IS_SUN3X) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/kernel/traps.c linux-bk/arch/m68k/kernel/traps.c
--- linux-2.4.19/arch/m68k/kernel/traps.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/kernel/traps.c	2002-11-22 15:35:31.000000000 +0000
@@ -816,8 +816,9 @@
 
 static inline int kernel_text_address(unsigned long addr)
 {
+#ifdef CONFIG_MODULES
 	struct module *mod;
-	int retval = 0;
+#endif
 	extern char _stext, _etext;
 
 	if (addr >= (unsigned long) &_stext &&
@@ -829,14 +830,12 @@
 		/* 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;
-		}
+		if (mod_bound(addr, 0, mod))
+			return 1;
 	}
 #endif
 
-	return retval;
+	return 0;
 }
 
 void show_trace(unsigned long *stack)
@@ -874,11 +873,14 @@
 	show_trace((unsigned long *)tsk->thread.esp0);
 }
 
-static void dump_stack(struct frame *fp)
+static void show_stack(struct frame *fp)
 {
 	unsigned long *stack, *endstack, addr;
 	int i;
 
+	if (fp == NULL)
+	    fp = (struct frame *)&fp;
+
 	addr = (unsigned long)&fp->un;
 	printk("Frame format=%X ", fp->ptregs.format);
 	switch (fp->ptregs.format) {
@@ -952,6 +954,14 @@
 	printk ("\n");
 }
 
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	show_stack(0);
+}
+
 void bad_super_trap (struct frame *fp)
 {
 	console_verbose();
@@ -1122,7 +1132,7 @@
 
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
-	dump_stack((struct frame *)fp);
+	show_stack((struct frame *)fp);
 	do_exit(SIGSEGV);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/config.c linux-bk/arch/m68k/mac/config.c
--- linux-2.4.19/arch/m68k/mac/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mac/config.c	2002-11-22 15:35:29.000000000 +0000
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 /* keyb */
 #include <linux/init.h>
+#include <linux/vt_kern.h>
 
 #define BOOTINFO_COMPAT_1_0
 #include <asm/setup.h>
@@ -47,6 +48,8 @@
 struct mac_booter_data mac_bi_data = {0,};
 int mac_bisize = sizeof mac_bi_data;
 
+struct mac_hw_present mac_hw_present;
+
 /* New m68k bootinfo stuff and videobase */
 
 extern int m68k_num_memory;
@@ -76,7 +79,6 @@
 extern void psc_init(void);
 extern void baboon_init(void);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 extern void mac_mksound(unsigned int, unsigned int);
 
 extern void nubus_sweep_video(void);
@@ -85,8 +87,6 @@
 extern void mac_debug_init(void);
 extern void mac_debugging_long(int, long);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
-
 extern int mackbd_init_hw(void);
 extern void mackbd_leds(unsigned int leds);
 extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);
@@ -207,7 +207,7 @@
 	if (!MACH_IS_MAC) {
 	  printk("ERROR: no Mac, but config_mac() called!! \n");
 	}
-	
+
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT_ADBHID
 	mach_keyb_init       = mac_hid_init_hw;
@@ -228,9 +228,12 @@
 	mach_keyb_init       = mackbd_init_hw;
 	mach_kbd_leds        = mackbd_leds;
 	mach_kbd_translate   = mackbd_translate;
+#ifdef CONFIG_MAGIC_SYSRQ
 	mach_sysrq_xlate     = mackbd_sysrq_xlate;
 	SYSRQ_KEY = 0x69;
+#endif /* CONFIG_MAGIC_SYSRQ */
 #endif /* CONFIG_INPUT_ADBHID */
+	kd_mksound		 = mac_mksound;
 #endif /* CONFIG_VT */
 
 	mach_sched_init      = mac_sched_init;
@@ -252,12 +255,13 @@
 	mach_reset           = mac_reset;
 	mach_halt            = mac_poweroff;
 	mach_power_off       = mac_poweroff;
+#ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp	         = &dummy_con;
+#endif
 	mach_max_dma_address = 0xffffffff;
 #if 0
 	mach_debug_init	 = mac_debug_init;
 #endif
-	kd_mksound		 = mac_mksound;
 #ifdef CONFIG_HEARTBEAT
 #if 0
 	mach_heartbeat = mac_heartbeat;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/debug.c linux-bk/arch/m68k/mac/debug.c
--- linux-2.4.19/arch/m68k/mac/debug.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mac/debug.c	2002-11-22 15:35:33.000000000 +0000
@@ -36,7 +36,7 @@
 extern unsigned long mac_videodepth;
 extern unsigned long mac_rowbytes;
 
-extern void mac_serial_print(char *);
+extern void mac_serial_print(const char *);
 
 #define DEBUG_HEADS
 #undef DEBUG_SCREEN
@@ -137,7 +137,7 @@
  * TODO: serial debug code
  */
 
-struct SCC
+struct mac_SCC
  {
   u_char cha_b_ctrl;
   u_char char_dummy1;
@@ -148,7 +148,7 @@
   u_char cha_a_data;
  };
 
-# define scc (*((volatile struct SCC*)mac_bi_data.sccbase))
+# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
 
 /* Flag that serial port is already initialized and used */
 int mac_SCC_init_done = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/macints.c linux-bk/arch/m68k/mac/macints.c
--- linux-2.4.19/arch/m68k/mac/macints.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-bk/arch/m68k/mac/macints.c	2002-11-22 15:35:27.000000000 +0000
@@ -249,7 +249,7 @@
 #endif /* SHUTUP_SONIC */
 
 	/* 
-	 * Now register the handlers for the the master IRQ handlers
+	 * Now register the handlers for the master IRQ handlers
 	 * at levels 1-7. Most of the work is done elsewhere.
 	 */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mac/misc.c linux-bk/arch/m68k/mac/misc.c
--- linux-2.4.19/arch/m68k/mac/misc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mac/misc.c	2002-11-22 15:35:31.000000000 +0000
@@ -229,8 +229,8 @@
 	do {
 		if (++ct > 10) {
 			printk("via_read_time: couldn't get valid time, "
-			       "last read = 0x%08X and 0x%08X\n", last_result.idata,
-			       result.idata);
+			       "last read = 0x%08lx and 0x%08lx\n",
+			       last_result.idata, result.idata);
 			break;
 		}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mm/fault.c linux-bk/arch/m68k/mm/fault.c
--- linux-2.4.19/arch/m68k/mm/fault.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mm/fault.c	2002-11-22 15:35:29.000000000 +0000
@@ -179,14 +179,12 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-	up_read(&mm->mmap_sem);
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-		down_read(&mm->mmap_sem);
+		yield();
 		goto survive;
 	}
-	
+
+	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mvme147/config.c linux-bk/arch/m68k/mvme147/config.c
--- linux-2.4.19/arch/m68k/mvme147/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mvme147/config.c	2002-11-22 15:35:26.000000000 +0000
@@ -103,8 +103,10 @@
 {
 	mach_max_dma_address	= 0x01000000;
 	mach_sched_init		= mvme147_sched_init;
+#ifdef CONFIG_VT
 	mach_keyb_init		= mvme147_keyb_init;
 	mach_kbdrate		= mvme147_kbdrate;
+#endif
 	mach_init_IRQ		= mvme147_init_IRQ;
 	mach_gettimeoffset	= mvme147_gettimeoffset;
 	mach_gettod		= mvme147_gettod;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/mvme16x/config.c linux-bk/arch/m68k/mvme16x/config.c
--- linux-2.4.19/arch/m68k/mvme16x/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/mvme16x/config.c	2002-11-22 15:35:27.000000000 +0000
@@ -145,14 +145,16 @@
 
     mach_max_dma_address = 0xffffffff;
     mach_sched_init      = mvme16x_sched_init;
+#ifdef CONFIG_VT
     mach_keyb_init       = mvme16x_keyb_init;
     mach_kbdrate         = mvme16x_kbdrate;
+/*  kd_mksound           = mvme16x_mksound; */
+#endif
     mach_init_IRQ        = mvme16x_init_IRQ;
     mach_gettimeoffset   = mvme16x_gettimeoffset;
     mach_gettod  	 = mvme16x_gettod;
     mach_hwclk           = mvme16x_hwclk;
     mach_set_clock_mmss	 = mvme16x_set_clock_mmss;
-/*  kd_mksound           = mvme16x_mksound; */
     mach_reset		 = mvme16x_reset;
     mach_free_irq	 = mvme16x_free_irq;
     mach_process_int	 = mvme16x_process_int;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/q40/config.c linux-bk/arch/m68k/q40/config.c
--- linux-2.4.19/arch/m68k/q40/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/q40/config.c	2002-11-22 15:35:31.000000000 +0000
@@ -23,6 +23,7 @@
 #include <linux/major.h>
 #include <linux/serial_reg.h>
 #include <linux/rtc.h>
+#include <linux/vt_kern.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -63,7 +64,6 @@
 extern void q40_waitbut(void);
 void q40_set_vectors (void);
 
-extern void (*kd_mksound)(unsigned int, unsigned int);
 void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
 
 extern char *saved_command_line;
@@ -164,42 +164,6 @@
     sprintf(model, "Q40");
 }
 
-/* pasted code to make parport_pc happy */
-extern __inline__ int __get_order(unsigned long size)
-{
-	int order;
-
-	size = (size-1) >> (PAGE_SHIFT-1);
-	order = -1;
-	do {
-		size >>= 1;
-		order++;
-	} while (size);
-	return order;
-}
-void *pci_alloc_consistent(void *hwdev, size_t size,
-			   dma_addr_t *dma_handle)
-{
-	void *ret;
-	int gfp = GFP_ATOMIC;
-
-	ret = (void *)__get_free_pages(gfp, __get_order(size));
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_bus(ret);
-	}
-	return ret;
-}
-
-void pci_free_consistent(void *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, __get_order(size));
-}
-/* end pasted code */
-
-
 /* No hardware options on Q40? */
 
 static int q40_get_hardware_list(char *buffer)
@@ -223,8 +187,11 @@
 {
     mach_sched_init      = q40_sched_init;
 
+#ifdef CONFIG_VT
     mach_keyb_init       = q40kbd_init_hw;
     mach_kbd_translate   = q40kbd_translate;
+    kd_mksound             = q40_mksound;
+#endif
     mach_init_IRQ        = q40_init_IRQ;   
     mach_gettimeoffset   = q40_gettimeoffset; 
     mach_gettod  	 = q40_gettod;
@@ -241,7 +208,6 @@
     mach_default_handler = &q40_sys_default_handler;
     mach_get_model       = q40_get_model;
     mach_get_hardware_list = q40_get_hardware_list;
-    kd_mksound             = q40_mksound;
 
 #ifdef CONFIG_MAGIC_SYSRQ
     mach_sysrq_key       = 0x54;
@@ -250,7 +216,9 @@
     mach_heartbeat = q40_heartbeat;
 #endif
     mach_halt = q40_halt;
+#ifdef CONFIG_DUMMY_CONSOLE
     conswitchp = &dummy_con;
+#endif
 
     /* disable a few things that SMSQ might have left enabled */
     q40_disable_irqs();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/config.c linux-bk/arch/m68k/sun3/config.c
--- linux-2.4.19/arch/m68k/sun3/config.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/sun3/config.c	2002-11-22 15:35:32.000000000 +0000
@@ -141,7 +141,9 @@
         mach_default_handler = &sun3_default_handler;
         mach_request_irq     =  sun3_request_irq;
         mach_free_irq        =  sun3_free_irq;
+#ifdef CONFIG_VT
 //	mach_keyb_init       =  sun3_keyb_init;
+#endif
 	enable_irq     	     =  sun3_enable_irq;
         disable_irq  	     =  sun3_disable_irq;
 	mach_process_int     =  sun3_process_int;
@@ -152,7 +154,7 @@
 	mach_get_model	     =  sun3_get_model;
 	mach_hwclk           =  sun3_hwclk;
 	mach_halt	     =  sun3_halt;
-#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_FB)
+#if !defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp 	     = &dummy_con;
 #endif
 
@@ -165,9 +167,9 @@
 	
 	sun3_bootmem_alloc(memory_start, memory_end);
 
+#ifdef CONFIG_SUN3X_ZS
 	sun_serial_setup();
-
-
+#endif
 }
 
 void __init sun3_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/mmu_emu.c linux-bk/arch/m68k/sun3/mmu_emu.c
--- linux-2.4.19/arch/m68k/sun3/mmu_emu.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-bk/arch/m68k/sun3/mmu_emu.c	2002-11-22 15:35:24.000000000 +0000
@@ -52,7 +52,9 @@
 
 /* pointers to the mm structs for each task in each
    context. 0xffffffff is a marker for kernel context */
-struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {0xffffffff, 0, 0, 0, 0, 0, 0, 0};
+struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {
+	(struct mm_struct *)0xffffffff, 0, 0, 0, 0, 0, 0, 0
+};
 /* has this context been mmdrop'd? */
 static unsigned char ctx_avail = CONTEXTS_NUM-1;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/sbus.c linux-bk/arch/m68k/sun3/sbus.c
--- linux-2.4.19/arch/m68k/sun3/sbus.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-bk/arch/m68k/sun3/sbus.c	2002-11-22 15:35:22.000000000 +0000
@@ -16,9 +16,9 @@
 
 void __init sbus_init(void)
 {
-
+#ifdef CONFIG_SUN3X_ZS
 	rs_init();
-
+#endif
 }
 
 void *sparc_alloc_io (u32 address, void *virtual, int len, char *name,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3/sun3ints.c linux-bk/arch/m68k/sun3/sun3ints.c
--- linux-2.4.19/arch/m68k/sun3/sun3ints.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-bk/arch/m68k/sun3/sun3ints.c	2002-11-22 15:35:30.000000000 +0000
@@ -99,7 +99,7 @@
 };
 static void (*sun3_vechandler[192])(int, void *, struct pt_regs *);
 static void *vec_ids[192];
-static char *vec_names[192];
+static const char *vec_names[192];
 
 static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
 {
@@ -122,8 +122,8 @@
 	sun3_inthandle, sun3_int5, sun3_inthandle, sun3_int7
 };
 
-static char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL, 
-				     NULL, "timer", NULL, NULL };
+static const char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL,
+					   NULL, "timer", NULL, NULL };
 
 void sun3_init_IRQ(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3x/config.c linux-bk/arch/m68k/sun3x/config.c
--- linux-2.4.19/arch/m68k/sun3x/config.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-bk/arch/m68k/sun3x/config.c	2002-11-22 15:35:23.000000000 +0000
@@ -61,9 +61,11 @@
 	mach_get_irq_list	 = sun3_get_irq_list;
 	mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
 
+#ifdef CONFIG_VT
 	mach_keyb_init       = sun3x_keyb_init;
 	mach_kbdrate         = sun3x_kbdrate;
 	mach_kbd_leds        = sun3x_kbd_leds;
+#endif
 
 	mach_default_handler = &sun3_default_handler;
 	mach_sched_init      = sun3x_sched_init;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3x/prom.c linux-bk/arch/m68k/sun3x/prom.c
--- linux-2.4.19/arch/m68k/sun3x/prom.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/sun3x/prom.c	2002-11-22 15:35:29.000000000 +0000
@@ -124,7 +124,8 @@
     idprom = &idprom_buffer;
 
     if((idprom->id_machtype & SM_ARCH_MASK) != SM_SUN3X) {
-	    printk("Warning: machine reports strange type %02x\n");
+	    printk("Warning: machine reports strange type %02x\n",
+		   idprom->id_machtype);
 	    printk("Pretending it's a 3/80, but very afraid...\n");
 	    idprom->id_machtype = SM_SUN3X | SM_3_80;
     }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/m68k/sun3x/time.c linux-bk/arch/m68k/sun3x/time.c
--- linux-2.4.19/arch/m68k/sun3x/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/m68k/sun3x/time.c	2002-11-22 15:35:31.000000000 +0000
@@ -62,8 +62,8 @@
 
 int sun3x_hwclk(int set, struct rtc_time *t)
 {
-	volatile struct mostek_dt *h = 
-		(unsigned char *)(SUN3X_EEPROM+M_CONTROL);
+	volatile struct mostek_dt *h =
+		(struct mostek_dt *)(SUN3X_EEPROM+M_CONTROL);
 	unsigned long flags;
 
 	save_and_cli(flags);
@@ -100,6 +100,7 @@
     return 0L;
 }
 
+#if 0
 static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
 {
     void (*vector)(int, void *, struct pt_regs *) = dev_id;
@@ -110,6 +111,7 @@
     
     vector(irq, NULL, regs);
 }
+#endif
 
 void __init sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *))
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/Makefile linux-bk/arch/mips/Makefile
--- linux-2.4.19/arch/mips/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/Makefile	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/Makefile linux-bk/arch/mips/arc/Makefile
--- linux-2.4.19/arch/mips/arc/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux-bk/arch/mips/arc/Makefile	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/arc_con.c linux-bk/arch/mips/arc/arc_con.c
--- linux-2.4.19/arch/mips/arc/arc_con.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-bk/arch/mips/arc/arc_con.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/cmdline.c linux-bk/arch/mips/arc/cmdline.c
--- linux-2.4.19/arch/mips/arc/cmdline.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/arc/cmdline.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/console.c linux-bk/arch/mips/arc/console.c
--- linux-2.4.19/arch/mips/arc/console.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/arc/console.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/identify.c linux-bk/arch/mips/arc/identify.c
--- linux-2.4.19/arch/mips/arc/identify.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/arc/identify.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/init.c linux-bk/arch/mips/arc/init.c
--- linux-2.4.19/arch/mips/arc/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/arc/init.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/memory.c linux-bk/arch/mips/arc/memory.c
--- linux-2.4.19/arch/mips/arc/memory.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/arc/memory.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/arc/salone.c linux-bk/arch/mips/arc/salone.c
--- linux-2.4.19/arch/mips/arc/salone.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/arc/salone.c	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/Makefile linux-bk/arch/mips/au1000/common/Makefile
--- linux-2.4.19/arch/mips/au1000/common/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/Makefile	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/clocks.c linux-bk/arch/mips/au1000/common/clocks.c
--- linux-2.4.19/arch/mips/au1000/common/clocks.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/clocks.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/dbg_io.c linux-bk/arch/mips/au1000/common/dbg_io.c
--- linux-2.4.19/arch/mips/au1000/common/dbg_io.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/dbg_io.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/dma.c linux-bk/arch/mips/au1000/common/dma.c
--- linux-2.4.19/arch/mips/au1000/common/dma.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/dma.c	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/int-handler.S linux-bk/arch/mips/au1000/common/int-handler.S
--- linux-2.4.19/arch/mips/au1000/common/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/int-handler.S	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/irq.c linux-bk/arch/mips/au1000/common/irq.c
--- linux-2.4.19/arch/mips/au1000/common/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/irq.c	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/power.c linux-bk/arch/mips/au1000/common/power.c
--- linux-2.4.19/arch/mips/au1000/common/power.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/power.c	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/prom.c linux-bk/arch/mips/au1000/common/prom.c
--- linux-2.4.19/arch/mips/au1000/common/prom.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/prom.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/reset.c linux-bk/arch/mips/au1000/common/reset.c
--- linux-2.4.19/arch/mips/au1000/common/reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/reset.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/rtc.c linux-bk/arch/mips/au1000/common/rtc.c
--- linux-2.4.19/arch/mips/au1000/common/rtc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/rtc.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/serial.c linux-bk/arch/mips/au1000/common/serial.c
--- linux-2.4.19/arch/mips/au1000/common/serial.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/serial.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/time.c linux-bk/arch/mips/au1000/common/time.c
--- linux-2.4.19/arch/mips/au1000/common/time.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/time.c	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/common/usbdev.c linux-bk/arch/mips/au1000/common/usbdev.c
--- linux-2.4.19/arch/mips/au1000/common/usbdev.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/common/usbdev.c	2002-11-22 15:35:23.000000000 +0000
@@ -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, devrequest* 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->value);
-		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->length);
-		switch (le16_to_cpu(setup->value) >> 8) {
+		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->value) & 0xff) == 0) {
+			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->value) & 0xff;
+			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",
-			    le16_to_cpu(setup->value) >> 8);
-			endpoint_stall(&serial->ep_ctrl);	// Stall endpoint 0
+	default:
+		// Invalid request
+		err("invalid get desc=%d, stalled",
+			    le16_to_cpu(setup->wValue) >> 8);
+		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->index) & 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->index) & 0xff;
-			serial->alternate_setting =
-			    le16_to_cpu(setup->value) & 0xff;
+	} 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->value) & 0xff;
-		dbg("set config, config=%d", serial->configuration);
-		if (!serial->configuration && serial->state > DEFAULT)
-			serial->state = ADDRESS;
-		else if (serial->configuration == 1)
-			serial->state = CONFIGURED;
-		else {
-			// FIXME: "respond with request error" - how?
-		}
-		break;
-	case USB_REQ_GET_CONFIGURATION:
-		// send serial->configuration
-		dbg("sending config");
-		send_packet(&serial->ep_ctrl, &serial->configuration, 1, 0);
-		break;
-	case USB_REQ_GET_STATUS:
-		// FIXME: looks like the h/w handles this one
-		switch (setup->requesttype) {
-		case 0x80:	// Device
-			// FIXME: send device status
-			break;
-		case 0x81:	// Interface
-			// FIXME: send interface status
-			break;
-		case 0x82:	// End Point
-			// FIXME: send endpoint status
-			break;
-		default:	// Invalid Command
-			endpoint_stall(&serial->ep_ctrl);	// Stall End Point 0
-			break;
-		}
-		break;
-	case USB_REQ_CLEAR_FEATURE:
-		switch (setup->requesttype) {
-		case 0x00:	// Device
-			if ((le16_to_cpu(setup->value) & 0xff) == 1)
-				serial->remote_wakeup_en = 0;
-			else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
-		case 0x02:	// End Point
-			if ((le16_to_cpu(setup->value) & 0xff) == 0) {
-				endpoint_t *ep =
-				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->index) & 0xff);
 
-				endpoint_unstall(ep);
-				endpoint_reset_datatoggle(ep);
-			} else
-				endpoint_stall(&serial->ep_ctrl);
-			break;
+	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->requesttype) {
-		case 0x00:	// Device
-			if ((le16_to_cpu(setup->value) & 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->value) & 0xff) == 0) {
-				endpoint_t *ep =
-				    epnum_to_ep(serial,
-						    le16_to_cpu(setup->index) & 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!
+
+	// 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)) {
-				devrequest setup;
-			if ((cs & (USBDEV_CS_NAK | USBDEV_CS_ACK)) ==
-			    USBDEV_CS_ACK)
-					dbg("got SETUP");
+#ifdef VDEBUG
+			if (pkt->status & PKT_STATUS_ACK)
+				vdbg("received SETUP");
 				else
-					dbg("got NAK SETUP, cs=%08x", cs);
-			memcpy(&setup, pkt->bufptr, sizeof(devrequest));
-				process_setup(serial, &setup);
-			//} else  FIXME: uncomment!
-			//dbg(__FUNCTION__ ": wrong size SETUP received");
-		} else {
-			// DATAx packet received on endpoint 0
-			// FIXME: will need a state machine for control
-			// OUT transactions
-			dbg("got DATAx on EP0, size=%d, cs=%08x",
-			    pkt->size, cs);
+				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
+	status = au_readl(USBD_INTSTAT);
+	au_writel(status, USBD_INTSTAT);	// ack'em
 
-#ifdef USBDEV_PIO
-	for (i = 0; i < 6; i++) {
-		if (status & (1 << (USBDEV_INT_HF_BIT + i))) {
-			endpoint_t *ep = fifonum_to_ep(serial, i);
-
-			if (ep->desc->bEndpointAddress & USB_DIR_IN)
-				endpoint_fifo_write(ep);
-			else
-				endpoint_fifo_read(ep);
-		}
-	}
-#endif
-
-	for (i = 0; i < 6; i++) {
-		if (status & (1 << i))
-			process_complete(serial, i);
-	}
+	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__);
 
-	if (!serial)
-		return;
+	*pkt = lpkt;
 
-	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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/Makefile linux-bk/arch/mips/au1000/pb1000/Makefile
--- linux-2.4.19/arch/mips/au1000/pb1000/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1000/Makefile	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/init.c linux-bk/arch/mips/au1000/pb1000/init.c
--- linux-2.4.19/arch/mips/au1000/pb1000/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1000/init.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/pci_fixup.c linux-bk/arch/mips/au1000/pb1000/pci_fixup.c
--- linux-2.4.19/arch/mips/au1000/pb1000/pci_fixup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1000/pci_fixup.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/pci_ops.c linux-bk/arch/mips/au1000/pb1000/pci_ops.c
--- linux-2.4.19/arch/mips/au1000/pb1000/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1000/pci_ops.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1000/setup.c linux-bk/arch/mips/au1000/pb1000/setup.c
--- linux-2.4.19/arch/mips/au1000/pb1000/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1000/setup.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/Makefile linux-bk/arch/mips/au1000/pb1100/Makefile
--- linux-2.4.19/arch/mips/au1000/pb1100/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1100/Makefile	2002-11-22 15:35:33.000000000 +0000
@@ -0,0 +1,24 @@
+#
+#  Copyright 2000,2001 MontaVista Software Inc.
+#  Author: MontaVista Software, Inc.
+#     	ppopov@mvista.com or source@mvista.com
+#
+# Makefile for the Alchemy Semiconductor 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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/init.c linux-bk/arch/mips/au1000/pb1100/init.c
--- linux-2.4.19/arch/mips/au1000/pb1100/init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1100/init.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/pci_fixup.c linux-bk/arch/mips/au1000/pb1100/pci_fixup.c
--- linux-2.4.19/arch/mips/au1000/pb1100/pci_fixup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1100/pci_fixup.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/pci_ops.c linux-bk/arch/mips/au1000/pb1100/pci_ops.c
--- linux-2.4.19/arch/mips/au1000/pb1100/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1100/pci_ops.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1100/setup.c linux-bk/arch/mips/au1000/pb1100/setup.c
--- linux-2.4.19/arch/mips/au1000/pb1100/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1100/setup.c	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/Makefile linux-bk/arch/mips/au1000/pb1500/Makefile
--- linux-2.4.19/arch/mips/au1000/pb1500/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1500/Makefile	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/init.c linux-bk/arch/mips/au1000/pb1500/init.c
--- linux-2.4.19/arch/mips/au1000/pb1500/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1500/init.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/pci_fixup.c linux-bk/arch/mips/au1000/pb1500/pci_fixup.c
--- linux-2.4.19/arch/mips/au1000/pb1500/pci_fixup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1500/pci_fixup.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/pci_ops.c linux-bk/arch/mips/au1000/pb1500/pci_ops.c
--- linux-2.4.19/arch/mips/au1000/pb1500/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1500/pci_ops.c	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/au1000/pb1500/setup.c linux-bk/arch/mips/au1000/pb1500/setup.c
--- linux-2.4.19/arch/mips/au1000/pb1500/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/au1000/pb1500/setup.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/boot/Makefile linux-bk/arch/mips/boot/Makefile
--- linux-2.4.19/arch/mips/boot/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/boot/Makefile	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/boot/addinitrd.c linux-bk/arch/mips/boot/addinitrd.c
--- linux-2.4.19/arch/mips/boot/addinitrd.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/boot/addinitrd.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/boot/elf2ecoff.c linux-bk/arch/mips/boot/elf2ecoff.c
--- linux-2.4.19/arch/mips/boot/elf2ecoff.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/boot/elf2ecoff.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/int-handler.S linux-bk/arch/mips/cobalt/int-handler.S
--- linux-2.4.19/arch/mips/cobalt/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/int-handler.S	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/irq.c linux-bk/arch/mips/cobalt/irq.c
--- linux-2.4.19/arch/mips/cobalt/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/irq.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/pci.c linux-bk/arch/mips/cobalt/pci.c
--- linux-2.4.19/arch/mips/cobalt/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/pci.c	2002-11-22 15:35:32.000000000 +0000
@@ -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);
@@ -403,13 +416,13 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-		unsigned long size)
+		unsigned long size, unsigned long align)
 {
 
 	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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/promcon.c linux-bk/arch/mips/cobalt/promcon.c
--- linux-2.4.19/arch/mips/cobalt/promcon.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/promcon.c	2002-11-22 15:35:34.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/reset.c linux-bk/arch/mips/cobalt/reset.c
--- linux-2.4.19/arch/mips/cobalt/reset.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/reset.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/setup.c linux-bk/arch/mips/cobalt/setup.c
--- linux-2.4.19/arch/mips/cobalt/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/setup.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/cobalt/via.c linux-bk/arch/mips/cobalt/via.c
--- linux-2.4.19/arch/mips/cobalt/via.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/cobalt/via.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/config-shared.in linux-bk/arch/mips/config-shared.in
--- linux-2.4.19/arch/mips/config-shared.in	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/config-shared.in	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/config.in linux-bk/arch/mips/config.in
--- linux-2.4.19/arch/mips/config.in	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/config.in	2002-11-22 15:35:32.000000000 +0000
@@ -4,631 +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 arch/mips/config-shared.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/Makefile linux-bk/arch/mips/ddb5074/Makefile
--- linux-2.4.19/arch/mips/ddb5074/Makefile	2001-04-14 03:26:07.000000000 +0000
+++ linux-bk/arch/mips/ddb5074/Makefile	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/irq.c linux-bk/arch/mips/ddb5074/irq.c
--- linux-2.4.19/arch/mips/ddb5074/irq.c	2001-04-14 03:26:07.000000000 +0000
+++ linux-bk/arch/mips/ddb5074/irq.c	2002-11-22 15:35:33.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/pci.c linux-bk/arch/mips/ddb5074/pci.c
--- linux-2.4.19/arch/mips/ddb5074/pci.c	2001-09-09 17:43:01.000000000 +0000
+++ linux-bk/arch/mips/ddb5074/pci.c	2002-11-22 15:35:30.000000000 +0000
@@ -396,7 +396,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5074/setup.c linux-bk/arch/mips/ddb5074/setup.c
--- linux-2.4.19/arch/mips/ddb5074/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5074/setup.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/Makefile linux-bk/arch/mips/ddb5xxx/common/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/common/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/common/Makefile	2002-11-22 15:35:28.000000000 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= ddb5xxx.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/irq.c linux-bk/arch/mips/ddb5xxx/common/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/common/irq.c	2002-11-22 15:35:32.000000000 +0000
@@ -13,6 +13,7 @@
  */
 #include <linux/config.h>
 #include <linux/init.h>
+#include <asm/irq.h>
 
 void (*irq_setup)(void);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/nile4.c linux-bk/arch/mips/ddb5xxx/common/nile4.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/nile4.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/common/nile4.c	2002-11-22 15:35:32.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/prom.c linux-bk/arch/mips/ddb5xxx/common/prom.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/prom.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/common/prom.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/common/rtc_ds1386.c linux-bk/arch/mips/ddb5xxx/common/rtc_ds1386.c
--- linux-2.4.19/arch/mips/ddb5xxx/common/rtc_ds1386.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/common/rtc_ds1386.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/Makefile linux-bk/arch/mips/ddb5xxx/ddb5074/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/Makefile	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/int-handler.S linux-bk/arch/mips/ddb5xxx/ddb5074/int-handler.S
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/int-handler.S	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/irq.c linux-bk/arch/mips/ddb5xxx/ddb5074/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/irq.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/nile4_pic.c linux-bk/arch/mips/ddb5xxx/ddb5074/nile4_pic.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/nile4_pic.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/nile4_pic.c	2002-11-22 15:35:28.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci.c linux-bk/arch/mips/ddb5xxx/ddb5074/pci.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/pci.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci_ops.c linux-bk/arch/mips/ddb5xxx/ddb5074/pci_ops.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/pci_ops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/pci_ops.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/setup.c linux-bk/arch/mips/ddb5xxx/ddb5074/setup.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/setup.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5074/time.c linux-bk/arch/mips/ddb5xxx/ddb5074/time.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5074/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5074/time.c	2002-11-22 15:35:23.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/Makefile linux-bk/arch/mips/ddb5xxx/ddb5476/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/Makefile	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/int-handler.S linux-bk/arch/mips/ddb5xxx/ddb5476/int-handler.S
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/int-handler.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/int-handler.S	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/irq.c linux-bk/arch/mips/ddb5xxx/ddb5476/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/irq.c	2002-11-22 15:35:29.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/nile4_pic.c linux-bk/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/nile4_pic.c	2002-11-22 15:35:31.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci.c linux-bk/arch/mips/ddb5xxx/ddb5476/pci.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/pci.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci_ops.c linux-bk/arch/mips/ddb5xxx/ddb5476/pci_ops.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/pci_ops.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/setup.c linux-bk/arch/mips/ddb5xxx/ddb5476/setup.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/setup.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux-bk/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/Makefile linux-bk/arch/mips/ddb5xxx/ddb5477/Makefile
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/Makefile	2002-11-22 15:35:27.000000000 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= ddb5477.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/debug.c linux-bk/arch/mips/ddb5xxx/ddb5477/debug.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/debug.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/debug.c	2002-11-22 15:35:25.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/int-handler.S linux-bk/arch/mips/ddb5xxx/ddb5477/int-handler.S
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/int-handler.S	2001-09-09 17:43:01.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/int-handler.S	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq.c linux-bk/arch/mips/ddb5xxx/ddb5477/irq.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/irq.c	2002-11-22 15:35:24.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq_5477.c linux-bk/arch/mips/ddb5xxx/ddb5477/irq_5477.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/irq_5477.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/irq_5477.c	2002-11-22 15:35:26.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci.c linux-bk/arch/mips/ddb5xxx/ddb5477/pci.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/pci.c	2002-11-22 15:35:30.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux-bk/arch/mips/ddb5xxx/ddb5477/pci_ops.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/pci_ops.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/pci_ops.c	2002-11-22 15:35:22.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/ddb5xxx/ddb5477/setup.c linux-bk/arch/mips/ddb5xxx/ddb5477/setup.c
--- linux-2.4.19/arch/mips/ddb5xxx/ddb5477/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/ddb5xxx/ddb5477/setup.c	2002-11-22 15:35:27.000000000 +0000
@@ -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 -Naur -X /home/marcelo/lib/dontdiff linux-2.4.19/arch/mips/dec/Makefile linux-bk/arch/mips/dec/Makefile
--- linux-2.4.19/arch/mips/dec/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-bk/arch/mips/dec/Makefile	2002-11-22 15:35:27.000000000 +0000
@@ -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)	+=lush.o
 obj--14,9 000, 		 *00 +0000dt@ -14,b +14,10 @@
 
 export-objs :=3.e_ident[EIrst_time) {
+		DBq,10 @F